aqualung-0.9beta11/0000777000175000001440000000000011331334362011175 500000000000000aqualung-0.9beta11/README0000644000175000001440000000167110746630174012007 00000000000000Aqualung README =============== Aqualung is an advanced music player primarily targeted at the GNU/Linux operating system, but also usable on FreeBSD, OpenBSD, Cygwin and also runs natively on Microsoft Windows. Homepage: http://aqualung.factorial.hu Please see the homepage for a general introduction to the program, including compilation instructions. Please refer to the documentation provided on the homepage for a detailed description of features, usage tips and miscellaneous info. Please consider subscribing to the project's mailing list at: http://lists.sourceforge.net/lists/listinfo/aqualung-friends General questions about compiling, usage etc. should go to this list rather than the developer's private address. This is also the place for development discussions. The primary place for bugreports is the project's web-based bugtracker at: http://aqualung.factorial.hu/mantis Enjoy, Tom Szilagyi aqualung-0.9beta11/configure.ac0000644000175000001440000007571211331330006013402 00000000000000# Process this file with autoconf to produce a configure script. AC_INIT(aqualung, 0.9beta11, http://aqualung.factorial.hu/mantis) AM_INIT_AUTOMAKE(aqualung, 0.9beta11) AC_CONFIG_SRCDIR([src/core.c]) AM_CONFIG_HEADER([config.h]) AC_MSG_CHECKING(for type of build) AC_ARG_ENABLE( debug, [ --enable-debug=yes,no compile with debugging support (default: no)], debug="$enableval", debug="no") if test "$debug" = "yes"; then buildtype=debug BUILD_CFLAGS="-rdynamic -ggdb -g -O0" AC_DEFINE([DEBUG_BUILD], [1], [Defined if doing a debug build]) AC_MSG_RESULT(debug) else buildtype=release BUILD_CFLAGS="-O2" AC_DEFINE([RELEASE_BUILD], [1], [Defined if doing a release build]) AC_MSG_RESULT(release) fi AC_MSG_CHECKING(for compilation platform) if test `uname -a | grep CYGWIN | wc -l` = "1" ; then PLATFORM_CFLAGS="-mwin32 -mwindows" PLATFORM_LIBS="-lintl -lwinmm" win32="yes" freebsd="no" openbsd="no" linux="no" if test "$buildtype" = "debug"; then AC_MSG_ERROR([Sorry, debug build under Cygwin is unsupported!]) fi platform="Cygwin" AC_MSG_RESULT(Cygwin) fi if test `uname -a | grep FreeBSD | wc -l` = "1" ; then PLATFORM_CFLAGS="" PLATFORM_LIBS="" win32="no" freebsd="yes" openbsd="no" linux="no" if test "$buildtype" = "debug"; then AC_MSG_ERROR([Sorry, debug build under FreeBSD is unsupported!]) fi platform="FreeBSD" AC_MSG_RESULT(FreeBSD) fi if test `uname -a | grep OpenBSD | wc -l` = "1" ; then PLATFORM_CFLAGS="" PLATFORM_LIBS="" win32="no" freebsd="no" openbsd="yes" linux="no" if test "$buildtype" = "debug"; then AC_MSG_ERROR([Sorry, debug build under OpenBSD is unsupported!]) fi platform="OpenBSD" AC_MSG_RESULT(OpenBSD) fi if test `uname -a | grep Linux | wc -l` = "1" ; then PLATFORM_CFLAGS="" PLATFORM_LIBS="" win32="no" freebsd="no" openbsd="no" linux="yes" platform="Linux" AC_MSG_RESULT(Linux) fi # Checks for programs. AC_PROG_CC AC_PROG_RANLIB AC_PROG_CXX AM_PROG_CC_C_O # Checks for header files. AC_HEADER_STDC AC_CHECK_HEADERS([errno.h fcntl.h stdlib.h string.h sys/ioctl.h unistd.h dlfcn.h]) # Checks for typedefs, structures, and compiler characteristics. AC_C_CONST AC_TYPE_SIZE_T # Checks for library functions. AC_PROG_GCC_TRADITIONAL AC_FUNC_MALLOC AC_FUNC_STAT AC_CHECK_FUNCS([floor memset mkdir strdup strrchr strstr strndup strcasestr]) AC_CHECK_PROG([var], [pkg-config], [yes], [no]) if test ! "$var" = "yes"; then AC_MSG_ERROR(You do not appear to have pkg-config installed) fi if test $win32 = "no" ; then AC_CHECK_LIB(pthread, pthread_create, [], [AC_MSG_ERROR(You do not appear to have a usable pthread library)]) fi if test $win32 = "no" -a $freebsd = "no" -a $openbsd = "no" ; then AC_CHECK_LIB(dl, dlopen, [], [AC_MSG_ERROR(You do not appear to have a usable interface to the dynamic linking loader.)]) fi z_LIBS="" AC_CHECK_LIB(z, gzopen, [lib=yes], [lib=no]) if test "$lib" = "yes"; then z_LIBS="-lz" AC_DEFINE([HAVE_LIBZ], [1], [Defined if compile with libz]) fi bz2_LIBS="" AC_CHECK_LIB(bz2, BZ2_bzopen, [lib=yes], [lib=no]) if test "$lib" = "yes"; then bz2_LIBS="-lbz2" AC_DEFINE([HAVE_LIBBZ2], [1], [Defined if compile with libbz2]) fi # Checks for libraries. AC_MSG_CHECKING(whether GTK+ version >= 2.6) if pkg-config --exists 'gtk+-2.0 >= 2.6'; then gtk_CFLAGS=`pkg-config --cflags gtk+-2.0` gtk_LIBS=`pkg-config --libs gtk+-2.0` glib_CFLAGS=`pkg-config --cflags gthread-2.0` glib_LIBS=`pkg-config --libs gthread-2.0` AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) AC_MSG_ERROR(GTK+ not found or too old (version < 2.6)) fi AC_CHECK_PROG([var], [xml2-config], [yes], [no]) if test ! "$var" = "yes"; then AC_MSG_ERROR(You do not appear to have xml2-config installed. This usually means that the libxml2 library is missing or not properly installed on your system. Get libxml2 from http://xmlsoft.org) fi xml_CFLAGS=`xml2-config --cflags` xml_LIBS=`xml2-config --libs` AC_CHECK_LIB(xml2, xmlNewDoc, [], [AC_MSG_ERROR(You do not appear to have libxml2 installed. Grab it from http://xmlsoft.org)]) AC_MSG_CHECKING(for sndio support) AC_ARG_WITH( sndio, [ --with-sndio=no,yes compile with sndio support (default: no)], sndio="$withval", sndio="no") if test "$oss" = no; then AC_MSG_RESULT(no) else AC_CHECK_HEADER([sndio.h], [hdr=yes], [hdr=no]) if test "$hdr" = "yes"; then AC_DEFINE([HAVE_SNDIO], [1], [Defined if compile with sndio support]) if test $openbsd = "yes" ; then AC_CHECK_LIB(sndio, sio_open, [sndio_LIBS="-lsndio"], [sndio_LIBS=""]) else sndio_LIBS="" fi fi if test "$hdr" = "no" -a "$sndio" = "yes"; then AC_MSG_ERROR(You do not appear to have sndio.h needed by sndio sound support.) fi fi AC_MSG_CHECKING(for OSS support) AC_ARG_WITH( oss, [ --with-oss=yes,no compile with OSS support (default: yes)], oss="$withval", oss="detect") if test "$oss" = no; then AC_MSG_RESULT(no) else if test $freebsd = "yes" ; then AC_CHECK_HEADER([sys/soundcard.h], [hdr=yes], [hdr=no]) elif test $openbsd = "yes" ; then AC_CHECK_HEADER([soundcard.h], [hdr=yes], [hdr=no]) elif test $linux = "yes" ; then AC_CHECK_HEADER([linux/soundcard.h], [hdr=yes], [hdr=no]) else hdr="no" AC_MSG_RESULT(no) fi if test "$hdr" = "yes"; then AC_DEFINE([HAVE_OSS], [1], [Defined if compile with OSS support]) if test $openbsd = "yes" ; then AC_CHECK_LIB(ossaudio, _oss_ioctl, [oss_LIBS="-lossaudio"], [oss_LIBS=""]) else oss_LIBS="" fi fi if test "$hdr" = "no" -a "$oss" = "yes"; then if test $freebsd = "yes" ; then AC_MSG_ERROR(You do not appear to have sys/soundcard.h needed by OSS sound support.) elif test $openbsd = "yes" ; then AC_MSG_ERROR(You do not appear to have soundcard.h needed by OSS sound support.) elif test $linux = "yes" ; then AC_MSG_ERROR(You do not appear to have linux/soundcard.h needed by OSS sound support.) else AC_MSG_ERROR(OSS output is unsupported on current build platform.) fi fi if test "$oss" = "detect"; then oss=$hdr fi fi AC_MSG_CHECKING(for ALSA support) AC_ARG_WITH( alsa, [ --with-alsa=yes,no compile with ALSA support (default: yes)], alsa="$withval", alsa="detect") if test "$alsa" = "no"; then AC_MSG_RESULT(no) else AC_CHECK_LIB(asound, snd_pcm_open, [lib=yes], [lib=no]) if test "$lib" = "yes"; then alsa_CFLAGS=`pkg-config --cflags alsa` alsa_LIBS=`pkg-config --libs alsa` AC_DEFINE([HAVE_ALSA], [1], [Defined if compile with ALSA support]) fi if test "$lib" = "no" -a "$alsa" = "yes"; then AC_MSG_ERROR(You do not appear to have the ALSA library installed) fi if test "$alsa" = "detect"; then alsa=$lib fi fi AC_MSG_CHECKING(for JACK support) AC_ARG_WITH( jack, [ --with-jack=yes,no compile with JACK support (default: yes)], jack="$withval", jack="detect") if test "$jack" = "no"; then AC_MSG_RESULT(no) else AC_CHECK_LIB(jack, jack_client_new, [lib=yes], [lib=no]) if test "$lib" = "yes"; then jack_CFLAGS=`pkg-config --cflags jack` jack_LIBS=`pkg-config --libs jack` AC_DEFINE([HAVE_JACK], [1], [Defined if compile with JACK support]) fi if test "$lib" = "no" -a "$jack" = "yes"; then AC_MSG_ERROR(You do not appear to have the JACK library installed. Grab it from http://jackaudio.org) fi if test "$jack" = "detect"; then jack=$lib fi fi AC_MSG_CHECKING(for PulseAudio support) AC_ARG_WITH( pulse, [ --with-pulse=yes,no compile with PulseAudio support (default: yes)], pulse="$withval", pulse="detect") if test "$pulse" = "no"; then AC_MSG_RESULT(no) else AC_CHECK_LIB(pulse-simple, pa_simple_new, [lib=yes], [lib=no]) if test "$lib" = "yes"; then pulse_CFLAGS=`pkg-config --cflags libpulse-simple` pulse_LIBS=`pkg-config --libs libpulse-simple` AC_DEFINE([HAVE_PULSE], [1], [Defined if compile with PulseAudio support]) fi if test "$lib" = "no" -a "$pulse" = "yes"; then AC_MSG_ERROR(You do not appear to have the PulseAudio installed. Grab it from http://pulseaudio.org/) fi if test "$pulse" = "detect"; then pulse=$lib fi fi AC_MSG_CHECKING(for Sample Rate Converter support) AC_ARG_WITH( src, [ --with-src=yes,no compile with Sample Rate Converter support (default: yes)], src="$withval", src="detect") if test "$src" = "no"; then AC_MSG_RESULT(no) else AC_CHECK_LIB(samplerate, src_new, [lib=yes], [lib=no]) if test "$lib" = "yes"; then src_LIBS=`pkg-config --libs samplerate` AC_DEFINE([HAVE_SRC], [1], [Defined if compile with Sample Rate Converter support]) fi if test "$lib" = "no" -a "$src" = "yes"; then AC_MSG_ERROR(You do not appear to have libsamplerate (aka. Secret Rabbit Code) installed. Grab it from http://www.mega-nerd.com/SRC/ ) fi if test "$src" = "detect"; then src=$lib fi fi AC_MSG_CHECKING(for sndfile support) AC_ARG_WITH( sndfile, [ --with-sndfile=yes,no compile with sndfile (WAV, AIFF, etc.) support (default: yes)], sndfile="$withval", sndfile="detect") if test "$sndfile" = "no"; then AC_MSG_RESULT(no) else AC_CHECK_LIB(sndfile, sf_open, [lib=yes], [lib=no]) if test "$lib" = "yes"; then sndfile_LIBS=`pkg-config --libs sndfile` AC_DEFINE([HAVE_SNDFILE], [1], [Defined if compile with sndfile (WAV, AIFF, etc.) support]) AC_MSG_CHECKING(whether sndfile version >= 1.0.12) if pkg-config --exists 'sndfile >= 1.0.12'; then AC_MSG_RESULT(yes) AC_DEFINE([HAVE_SNDFILE_1_0_12], [1], [Defined if version(sndfile) >= 1.0.12]) else AC_MSG_RESULT(no) fi AC_MSG_CHECKING(whether sndfile version >= 1.0.18) if pkg-config --exists 'sndfile >= 1.0.18'; then AC_MSG_RESULT(yes) AC_DEFINE([HAVE_SNDFILE_1_0_18], [1], [Defined if version(sndfile) >= 1.0.18]) else AC_MSG_RESULT(no) fi fi if test "$lib" = "no" -a "$sndfile" = "yes"; then AC_MSG_ERROR(You do not appear to have the sndfile library installed. Grab it from http://www.mega-nerd.com/libsndfile/ ) fi if test "$sndfile" = "detect"; then sndfile=$lib fi fi AC_MSG_CHECKING(for FLAC support) AC_ARG_WITH( flac, [ --with-flac=yes,no compile with FLAC support (default: yes)], flac="$withval", flac="detect") if test "$flac" = "no"; then AC_MSG_RESULT(no) else AC_CHECK_LIB(FLAC, FLAC__stream_decoder_init_file, [lib=yes], [lib=no], [-logg]) if test "$lib" = "yes"; then flac_LIBS="-lFLAC" AC_DEFINE([HAVE_FLAC_8], [1], [Defined if compile with FLAC (1.1.3 and newer API)]) AC_DEFINE([HAVE_FLAC], [1], [Defined if compile with some kind of FLAC support]) fi AC_CHECK_LIB(FLAC, FLAC__file_decoder_new, [lib2=yes], [lib2=no]) if test "$lib2" = "yes"; then flac_LIBS="-lFLAC" AC_DEFINE([HAVE_FLAC_7], [1], [Defined if compile with FLAC (1.1.2 and older API)]) AC_DEFINE([HAVE_FLAC], [1], [Defined if compile with some kind of FLAC support]) fi if test "$lib" = "no" -a "$lib2" = "no" -a "$flac" = "yes"; then AC_MSG_ERROR(You do not appear to have the FLAC library installed. Grab it from http://flac.sourceforge.net) fi if test "$flac" = "detect"; then if test "$lib2" = "yes" -o "$lib" = "yes"; then flac="yes" else flac="no" AC_MSG_RESULT(no) fi fi fi AC_MSG_CHECKING(for Ogg Vorbis support) AC_ARG_WITH( ogg, [ --with-ogg=yes,no compile with Ogg Vorbis support (default: yes)], ogg="$withval", ogg="detect") if test "$ogg" = "no"; then AC_MSG_RESULT(no) else AC_CHECK_LIB(vorbis, ov_open, [lib=yes], [lib=no], [-lvorbisfile -logg]) if test "$lib" = "yes"; then ogg_LIBS="-logg -lvorbis -lvorbisfile" AC_DEFINE([HAVE_OGG_VORBIS], [1], [Defined if compile with Ogg Vorbis support]) fi if test "$lib" = "no" -a "$ogg" = "yes"; then AC_MSG_ERROR(You do not appear to have the ogg, vorbis and vorbisfile libraries installed. Grab them from http://www.xiph.org/ogg/vorbis) fi if test "$ogg" = "detect"; then ogg=$lib fi fi AC_MSG_CHECKING(for Ogg Vorbis encoding support) AC_ARG_WITH( vorbisenc, [ --with-vorbisenc=yes,no compile with Ogg Vorbis encoding support (default: yes)], vorbisenc="$withval", vorbisenc="detect") if test "$vorbisenc" = "no"; then AC_MSG_RESULT(no) else AC_CHECK_LIB(vorbisenc, vorbis_encode_setup_init, [lib=yes], [lib=no], [-lvorbis -logg]) if test "$lib" = "yes"; then vorbisenc_LIBS="-logg -lvorbis -lvorbisenc" AC_DEFINE([HAVE_VORBISENC], [1], [Defined if compile with Ogg Vorbis encoding support]) fi if test "$lib" = "no" -a "$vorbisenc" = "yes"; then AC_MSG_ERROR(You do not appear to have the ogg, vorbis and vorbisenc libraries installed. Grab them from http://www.xiph.org/ogg/vorbis) fi if test "$vorbisenc" = "detect"; then vorbisenc=$lib fi fi AC_MSG_CHECKING(for Ogg Speex support) AC_ARG_WITH( speex, [ --with-speex=yes,no compile with Ogg Speex support (default: yes)], speex="$withval", speex="detect") if test "$speex" = "no"; then AC_MSG_RESULT(no) else AC_CHECK_LIB(oggz, oggz_open, [oggzlib=yes], [oggzlib=no], [-loggz -logg]) AC_CHECK_LIB(speex, speex_bits_init, [speexlib=yes], [speexlib=no], [-lspeex]) if test "$oggzlib" = "yes"; then if test "$speexlib" = "yes"; then speex_LIBS="-loggz -logg -lspeex" lib="yes" AC_DEFINE([HAVE_SPEEX], [1], [Defined if compile with Ogg Speex support]) else lib="no" fi else lib="no" fi if test "$lib" = "no" -a "$speex" = "yes"; then AC_MSG_ERROR(You do not appear to have the oggz and speex libraries installed. Grab them from http://www.annodex.net/software/liboggz and http://speex.org) fi if test "$speex" = "detect"; then speex=$lib fi fi AC_MSG_CHECKING(for MPEG audio support) AC_ARG_WITH( mpeg, [ --with-mpeg=yes,no compile with MPEG Audio support (default: yes)], mpeg="$withval", mpeg="detect") if test "$mpeg" = "no"; then AC_MSG_RESULT(no) else AC_CHECK_HEADER([mad.h], [hdr=yes], [hdr=no]) if test "$hdr" = "no"; then lib="no" else AC_CHECK_LIB(mad, mad_decoder_init, [lib=yes], [lib=no]) if test "$lib" = "yes"; then mad_LIBS="-lmad" AC_DEFINE([HAVE_MPEG], [1], [Defined if compile with MPEG Audio support]) fi fi if test "$lib" = "no" -a "$mpeg" = "yes"; then AC_MSG_ERROR(You do not appear to have the MAD library installed. Grab it from http://www.underbit.com/products/mad/) fi if test "$mpeg" = "detect"; then mpeg=$lib fi fi AC_MSG_CHECKING(for MOD audio support) AC_ARG_WITH( mod, [ --with-mod=yes,no compile with MOD Audio support (default: yes)], mod="$withval", mod="detect") if test "$mod" = "no"; then AC_MSG_RESULT(no) else AC_CHECK_LIB(modplug, ModPlug_Load, [lib=yes], [lib=no], [-lstdc++ -lm]) if test "$lib" = "yes"; then mod_LIBS=`pkg-config --libs libmodplug` AC_DEFINE([HAVE_MOD], [1], [Defined if compile with MOD Audio support]) fi if test "$lib" = "no" -a "$mod" = "yes"; then AC_MSG_ERROR(You do not appear to have the libmodplug library installed. Grab it from http://modplug-xmms.sourceforge.net/) fi if test "$mod" = "detect"; then mod=$lib fi if test "$mod" = "yes"; then AC_MSG_CHECKING(for Module info) AC_MSG_CHECKING(whether libmodplug version >= 0.8) if pkg-config --exists 'libmodplug >= 0.8'; then AC_MSG_RESULT(yes) AC_DEFINE([HAVE_MOD_INFO], [1], [Defined if version(libmodplug) >= 0.8]) else AC_MSG_RESULT(no) fi fi fi AC_MSG_CHECKING(for Musepack support) AC_ARG_WITH( mpc, [ --with-mpc=yes,no compile with Musepack support (default: yes)], mpc="$withval", mpc="detect") if test "$mpc" = "no"; then AC_MSG_RESULT(no) else AC_CHECK_LIB([mpcdec], [mpc_demux_init], [lib=yes], [AC_CHECK_LIB([mpcdec], [mpc_streaminfo_init], [lib=yes AC_DEFINE([MPC_OLD_API], [1], [Defined if old Musepack API is used])], [], [-lstdc++])], [-lstdc++]) if test "$lib" = "yes"; then mpc_LIBS="-lmpcdec -lstdc++" AC_DEFINE([HAVE_MPC], [1], [Defined if compile with Musepack support]) fi if test "$lib" != "yes" -a "$mpc" = "yes"; then AC_MSG_ERROR(You do not appear to have the Musepack decoder library (libmpcdec) installed. Grab it from http://www.musepack.net) fi if test "$mpc" = "detect"; then mpc=$lib fi fi AC_MSG_CHECKING(for Monkey's Audio Codec support) AC_ARG_WITH( mac, [ --with-mac=yes,no compile with Monkey's Audio Codec support (default: yes)], mac="$withval", mac="detect") if test "$mac" = "no"; then AC_MSG_RESULT(no) mac_LIBS="-lstdc++" else AC_CHECK_LIB(mac, CreateIAPEDecompress, [lib=yes], [lib=no], [-lstdc++]) if test "$lib" = "yes"; then mac_LIBS="-lmac -lstdc++" AC_DEFINE([HAVE_MAC], [1], [Defined if compile with Monkey's Audio Codec support]) else mac_LIBS="-lstdc++" fi if test "$lib" = "no" -a "$mac" = "yes"; then AC_MSG_ERROR(You do not appear to have the Monkey's Audio Codec decoder library installed. Grab it from http://etree.org/shnutils/shntool/support/formats/ape/unix/) fi if test "$mac" = "detect"; then mac=$lib fi fi AC_MSG_CHECKING(for LAVC support) AC_ARG_WITH( lavc, [ --with-lavc=yes,no compile with lavc (FFmpeg) support (default: yes)], lavc="$withval", lavc="detect") if test "$lavc" = "no"; then AC_MSG_RESULT(no) else AC_CHECK_HEADER([avcodec.h], [avc_hdr=yes], [avc_hdr=no]) if test "$avc_hdr" = "yes"; then AC_DEFINE([HAVE_AVCODEC_H], [1], [Define to 1 if you have the header file.]) else AC_CHECK_HEADER([ffmpeg/avcodec.h], [avc_hdr=yes], [avc_hdr=no]) if test "$avc_hdr" = "yes"; then AC_DEFINE([HAVE_FFMPEG_AVCODEC_H], [1], [Define to 1 if you have the header file.]) else AC_CHECK_HEADER([libavcodec/avcodec.h], [avc_hdr=yes], [avc_hdr=no]) if test "$avc_hdr" = "yes"; then AC_DEFINE([HAVE_LIBAVCODEC_AVCODEC_H], [1], [Define to 1 if you have the header file.]) else AC_CHECK_HEADER([ffmpeg/libavcodec/avcodec.h], [avc_hdr=yes], [avc_hdr=no]) if test "$avc_hdr" = "yes"; then AC_DEFINE([HAVE_FFMPEG_LIBAVCODEC_AVCODEC_H], [1], [Define to 1 if you have the header file.]) else PKG_CHECK_MODULES(LIBAVCODEC, libavcodec, [avc_hdr=yes], [avc_hdr=no]) if test "$avc_hdr" = "yes"; then AC_DEFINE([HAVE_LIBAVCODEC_AVCODEC_H], [1], [Define to 1 if you have the header file.]) fi fi fi fi fi AC_CHECK_HEADER([avformat.h], [avf_hdr=yes], [avf_hdr=no]) if test "$avf_hdr" = "yes"; then AC_DEFINE([HAVE_AVFORMAT_H], [1], [Define to 1 if you have the header file.]) else AC_CHECK_HEADER([ffmpeg/avformat.h], [avf_hdr=yes], [avf_hdr=no]) if test "$avf_hdr" = "yes"; then AC_DEFINE([HAVE_FFMPEG_AVFORMAT_H], [1], [Define to 1 if you have the header file.]) else AC_CHECK_HEADER([libavformat/avformat.h], [avf_hdr=yes], [avf_hdr=no]) if test "$avf_hdr" = "yes"; then AC_DEFINE([HAVE_LIBAVFORMAT_AVFORMAT_H], [1], [Define to 1 if you have the header file.]) else AC_CHECK_HEADER([ffmpeg/libavformat/avformat.h], [avf_hdr=yes], [avf_hdr=no]) if test "$avf_hdr" = "yes"; then AC_DEFINE([HAVE_FFMPEG_LIBAVFORMAT_AVFORMAT_H], [1], [Define to 1 if you have the header file.]) else PKG_CHECK_MODULES(LIBAVFORMAT, libavformat, [avf_hdr=yes], [avf_hdr=no]) if test "$avf_hdr" = "yes"; then AC_DEFINE([HAVE_LIBAVFORMAT_AVFORMAT_H], [1], [Define to 1 if you have the header file.]) fi fi fi fi fi AC_CHECK_LIB(avformat, av_open_input_file, [avf_lib=yes], [avf_lib=no], [-lavcodec -lavutil -lz]) AC_CHECK_LIB(avcodec, avcodec_open, [avc_lib=yes], [avc_lib=no], [-lavformat -lavutil -lz]) if test "$avc_hdr" = "yes" -a "$avf_hdr" = "yes" -a "$avc_lib" = "yes" -a "$avf_lib" = "yes" ; then lavc_LIBS="-lavformat -lavcodec -lavutil -lz" AC_DEFINE([HAVE_LAVC], [1], [Defined if compile with LAVC support]) lavc="yes" else if test "$lavc" = "yes"; then AC_MSG_ERROR(You do not appear to have the LAVC decoder library (FFmpeg) installed. Grab it from http://ffmpeg.mplayerhq.hu/) fi lavc="no" fi fi AC_MSG_CHECKING(for LAME (MP3 encoding) support) AC_ARG_WITH( lame, [ --with-lame=yes,no compile with LAME (MP3 encoding) support (default: yes)], lame="$withval", lame="detect") if test "$lame" = "no"; then AC_MSG_RESULT(no) else AC_CHECK_LIB(mp3lame, lame_init, [lib=yes], [lib=no]) if test "$lib" = "yes"; then lame_LIBS="-lmp3lame" AC_DEFINE([HAVE_LAME], [1], [Defined if compile with LAME support]) fi if test "$lib" = "no" -a "$lame" = "yes"; then AC_MSG_ERROR(You do not appear to have the LAME library installed. Grab it from http://lame.sourceforge.net/) fi if test "$lame" = "detect"; then lame=$lib fi fi AC_MSG_CHECKING(for WavPack support) AC_ARG_WITH( wavpack, [ --with-wavpack=yes,no compile with WavPack support (default: yes)], wavpack="$withval", wavpack="detect") if test "$wavpack" = "no"; then AC_MSG_RESULT(no) else AC_CHECK_LIB(wavpack, WavpackOpenFileInput, [lib=yes], [lib=no]) if test "$lib" = "yes"; then wavpack_LIBS=`pkg-config --libs wavpack` AC_MSG_CHECKING(whether WavPack version >= 4.40.0) if pkg-config --exists 'wavpack >= 4.40.0'; then AC_MSG_RESULT(yes) AC_DEFINE([HAVE_WAVPACK], [1], [Defined if compile with Wavpack support]) else lib="no" AC_MSG_RESULT(no) fi fi if test "$lib" = "no" -a "$wavpack" = "yes"; then AC_MSG_ERROR([You do not appear to have the WavPack library installed, or it is older than the required version (4.40.0). Grab it from http://www.wavpack.com]) fi if test "$wavpack" = "detect"; then wavpack=$lib fi fi AC_MSG_CHECKING(for LADSPA plugin support) AC_ARG_WITH( ladspa, [ --with-ladspa=yes,no compile with LADSPA plugin support (default: yes)], ladspa="$withval", ladspa="detect") if test "$ladspa" = "no"; then AC_MSG_RESULT(no) else AC_CHECK_LIB(lrdf, lrdf_init, [lib=yes], [lib=no]) if test "$lib" = "yes"; then AC_MSG_CHECKING(whether liblrdf version >= 0.4.0) if `pkg-config --exists 'lrdf >= 0.4.0'`; then AC_MSG_RESULT(yes) lrdf_LIBS=`pkg-config --libs lrdf` AC_DEFINE([HAVE_LADSPA], [1], [Defined if compile with LADSPA plugin support]) else AC_MSG_RESULT(no) lib="no" fi fi if test "$lib" = "no" -a "$ladspa" = "yes"; then AC_MSG_ERROR(You do not appear to have the LRDF library installed (needed for LADSPA support). Grab it from http://sourceforge.net/projects/lrdf/) fi if test "$ladspa" = "detect"; then ladspa=$lib fi fi AC_MSG_CHECKING(for CDDA support) AC_ARG_WITH( cdda, [ --with-cdda=yes,no compile with CDDA support (default: yes)], cdda="$withval", cdda="detect") if test "$cdda" = "no"; then AC_MSG_RESULT(no) else if test $win32 = "no" ; then AC_CHECK_LIB(cdio, cdio_open, [lib=yes], [lib=no]) else AC_CHECK_LIB(cdio, cdio_open, [lib=yes], [lib=no], [-lwinmm]) fi if test "$lib" = "yes"; then AC_MSG_CHECKING(whether libcdio_paranoia version >= 0.76) if `pkg-config --exists 'libcdio_paranoia >= 0.76'`; then cdda_CFLAGS=`pkg-config --cflags libcdio_paranoia` cdda_LIBS=`pkg-config --libs libcdio_paranoia` AC_DEFINE([HAVE_CDDA], [1], [Defined if compile with CDDA support]) AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) lib="no" fi fi if test "$lib" = "no" -a "$cdda" = "yes"; then AC_MSG_ERROR(libcdio and/or libcdio_paranoia library not found or too old. Grab it from http://www.gnu.org/software/libcdio/) fi if test "$cdda" = "detect"; then cdda=$lib fi fi AC_MSG_CHECKING(for CDDB support) AC_ARG_WITH( cddb, [ --with-cddb=yes,no compile with CDDB support (default: yes)], cddb="$withval", cddb="detect") if test "$cddb" = "no"; then AC_MSG_RESULT(no) else AC_CHECK_LIB(cddb, cddb_new, [lib=yes], [lib=no]) if test "$lib" = "yes"; then AC_MSG_CHECKING(whether libcddb version >= 1.2.1) if `pkg-config --exists 'libcddb >= 1.2.1'`; then AC_MSG_RESULT(yes) cddb_LIBS=`pkg-config --libs libcddb` AC_DEFINE([HAVE_CDDB], [1], [Defined if compile with CDDB support]) AC_CHECK_LIB(cddb, cddb_disc_get_revision, [libcddb_rev=yes], [libcddb_rev=no]) if test "$libcddb_rev" = "yes"; then AC_DEFINE([LIBCDDB_REVISION], [1], [Defined if libcddb handles disc revision number]) fi else AC_MSG_RESULT(no) lib="no" fi fi if test "$lib" = "no" -a "$cddb" = "yes"; then AC_MSG_ERROR(CDDB library not found or too old (version < 1.2.1). Grab it from http://libcddb.sf.net/) fi if test "$cddb" = "detect"; then cddb=$lib fi fi AC_MSG_CHECKING(for iRiver iFP support) AC_ARG_WITH( ifp, [ --with-ifp=yes,no compile with iRiver iFP driver support (default: yes)], ifp="$withval", ifp="detect") if test "$ifp" = "no"; then AC_MSG_RESULT(no) else AC_CHECK_LIB(usb, usb_init, [lib=yes], [lib=no]) if test "$lib" = "yes"; then AC_CHECK_LIB(ifp, ifp_find_device, [lib=yes], [lib=no]) if test "$lib" = "yes"; then ifp_LIBS="-lifp -lusb" AC_DEFINE([HAVE_IFP], [1], [Defined if compile with iRiver iFP driver support]) fi if test "$lib" = "no" -a "$ifp" = "yes"; then AC_MSG_ERROR(You do not appear to have the iFP driver library installed. Grab it from http://ifp-driver.sourceforge.net/) fi fi if test "$ifp" = "detect"; then ifp=$lib fi fi AC_MSG_CHECKING(for Systray support) AC_ARG_WITH( systray, [ --with-systray=yes,no compile with Systray support (default: yes)], systray="$withval", systray="detect") if test "$systray" = "no"; then AC_MSG_RESULT(no) else AC_MSG_CHECKING(whether GTK+ version >= 2.10) if pkg-config --exists 'gtk+-2.0 >= 2.10'; then AC_MSG_RESULT(yes) AC_DEFINE([HAVE_SYSTRAY], [1], [Defined if version(GTK+-2.0) >= 2.10]) lib="yes" else AC_MSG_RESULT(no) lib="no" fi if test "$lib" = "no" -a "$systray" = "yes"; then AC_MSG_ERROR(You need GTK+ version 2.10 or higher for systray support.) fi if test "$systray" = "detect"; then systray=$lib fi fi AC_MSG_CHECKING(for loop playback support) AC_ARG_WITH( loop, [ --with-loop=yes,no compile with loop playback support (default: yes)], loop="$withval", loop="detect") if test "$loop" = "no"; then AC_MSG_RESULT(no) else AC_MSG_CHECKING(whether GTK+ version >= 2.8) if pkg-config --exists 'gtk+-2.0 >= 2.8'; then AC_MSG_RESULT(yes) AC_DEFINE([HAVE_LOOP], [1], [Defined if version(GTK+-2.0) >= 2.8]) lib="yes" else AC_MSG_RESULT(no) lib="no" fi if test "$lib" = "no" -a "$loop" = "yes"; then AC_MSG_ERROR(You need GTK+ version 2.8 or higher for loop playback support.) fi if test "$loop" = "detect"; then loop=$lib fi fi AC_MSG_CHECKING(for podcast support) AC_ARG_WITH( podcast, [ --with-podcast=yes,no compile with podcast support (default: yes)], podcast="$withval", podcast="yes") if test "$podcast" = "no"; then AC_MSG_RESULT(no) else AC_DEFINE([HAVE_PODCAST], [1], [Defined if compile with podcast support]) AC_MSG_RESULT(yes) fi AC_MSG_CHECKING(for Lua support) AC_ARG_WITH( lua, [ --with-lua=yes,no compile with Lua (programmable title formatting) support (default: yes)], lua="$withval", lua="detect") if test "$lua" = "no"; then AC_MSG_RESULT(no) else AC_CHECK_LIB(lua, lua_load, [lib=yes], [lib=no]) if test "$lib" = "yes"; then lua_LIBS="-llua" AC_DEFINE([HAVE_LUA], [1], [Defined if compiled with Lua support]) else AC_CHECK_LIB(lua5.1, lua_load, [lib=yes], [lib=no]) if test "$lib" = "yes"; then lua_LIBS="-llua5.1" AC_DEFINE([HAVE_LUA], [1], [Defined if compiled with Lua support]) AC_DEFINE([LUA_HEADER_lua5_1], [1], [Defined if lua headers detected in a nonstandard location]) fi fi if test "$lib" = "no" -a "$lua" = "yes"; then AC_MSG_ERROR(You do not appear to have the Lua 5.1 library installed. Grab it from http://www.lua.org/.) fi if test "$lua" = "detect"; then lua=$lib fi fi # Compiler and linker variables AQUALUNG_SKINDIR="-DAQUALUNG_SKINDIR=\\\"$datadir/aqualung/skin\\\"" AQUALUNG_LOCALEDIR="-DAQUALUNG_LOCALEDIR=\\\"$datadir/locale\\\"" AQUALUNG_DATADIR="-DAQUALUNG_DATADIR=\\\"$datadir/aqualung\\\"" CFLAGS="$CFLAGS $BUILD_CFLAGS -Wall $PLATFORM_CFLAGS $AQUALUNG_SKINDIR $AQUALUNG_LOCALEDIR $AQUALUNG_DATADIR -D_GNU_SOURCE" CXXFLAGS="$CFLAGS" CPPFLAGS="$gtk_CFLAGS $glib_CFLAGS $xml_CFLAGS $alsa_CFLAGS $jack_CFLAGS $cdda_CFLAGS $pulse_CFLAGS" LIBS="decoder/libdecoder.a encoder/libencoder.a $gtk_LIBS $glib_LIBS $xml_LIBS $jack_LIBS $lrdf_LIBS $src_LIBS $alsa_LIBS $sndio_LIBS $oss_LIBS $sndfile_LIBS $flac_LIBS $ogg_LIBS $wavpack_LIBS $speex_LIBS $mad_LIBS $mod_LIBS $mpc_LIBS $mac_LIBS $lavc_LIBS $vorbisenc_LIBS $lame_LIBS $cdda_LIBS $cddb_LIBS $ifp_LIBS $PLATFORM_LIBS $z_LIBS $bz2_LIBS $lua_LIBS $pulse_LIBS" AC_OUTPUT([Makefile \ doc/Makefile \ skin/Makefile \ skin/dark/Makefile \ skin/default/Makefile \ skin/metal/Makefile \ skin/ocean/Makefile \ skin/plain/Makefile \ skin/woody/Makefile \ skin/no_skin/Makefile \ src/Makefile \ src/decoder/Makefile \ src/encoder/Makefile \ src/img/Makefile \ src/po/Makefile]) echo "----------------------------------------------------------------------" echo " Configuration summary" echo " =====================" echo echo " Build type / target platform : $buildtype / $platform" echo echo " Optional features:" echo " LADSPA plugin support : $ladspa" echo " CDDA (Audio CD) support : $cdda" echo " CDDB support : $cddb" echo " Sample Rate Converter support : $src" echo " iRiver iFP driver support : $ifp" echo " Loop playback support : $loop" echo " Systray support : $systray" echo " Podcast support : $podcast" echo " Lua (prog. title format) support : $lua" echo echo " Decoding support:" echo " sndfile (WAV, AIFF, AU, etc.) : $sndfile" echo " Free Lossless Audio Codec (FLAC) : $flac" echo " Ogg Vorbis : $ogg" echo " Ogg Speex : $speex" echo " MPEG Audio (MPEG 1-2.5 Layer I-III) : $mpeg" echo " MOD Audio (MOD, S3M, XM, IT, etc.) : $mod" echo " Musepack : $mpc" echo " Monkey's Audio Codec : $mac" echo " WavPack : $wavpack" echo " LAVC (AC3, AAC, WavPack, WMA, etc.) : $lavc" echo echo " Encoding support:" echo " sndfile (WAV) : $sndfile" echo " Free Lossless Audio Codec (FLAC) : $flac" echo " Ogg Vorbis : $vorbisenc" echo " LAME (MP3) : $lame" echo echo " Output driver support:" echo " sndio Audio : $sndio" echo " OSS Audio : $oss" echo " ALSA Audio : $alsa" echo " JACK Audio Server : $jack" echo " PulseAudio : $pulse" echo " Win32 Sound API : $win32" echo echo "----------------------------------------------------------------------" aqualung-0.9beta11/aclocal.m40000644000175000001440000011470111331330027012747 00000000000000# generated automatically by aclocal 1.10.2 -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # 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. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.63],, [m4_warning([this file was generated for autoconf 2.63. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically `autoreconf'.])]) # pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- # # Copyright © 2004 Scott James Remnant . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # 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. # PKG_PROG_PKG_CONFIG([MIN-VERSION]) # ---------------------------------- AC_DEFUN([PKG_PROG_PKG_CONFIG], [m4_pattern_forbid([^_?PKG_[A-Z_]+$]) m4_pattern_allow([^PKG_CONFIG(_PATH)?$]) AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])dnl if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) fi if test -n "$PKG_CONFIG"; then _pkg_min_version=m4_default([$1], [0.9.0]) AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) PKG_CONFIG="" fi fi[]dnl ])# PKG_PROG_PKG_CONFIG # PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) # # Check to see whether a particular set of modules exists. Similar # to PKG_CHECK_MODULES(), but does not set variables or print errors. # # # Similar to PKG_CHECK_MODULES, make sure that the first instance of # this or PKG_CHECK_MODULES is called, or make sure to call # PKG_CHECK_EXISTS manually # -------------------------------------------------------------- AC_DEFUN([PKG_CHECK_EXISTS], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl if test -n "$PKG_CONFIG" && \ AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then m4_ifval([$2], [$2], [:]) m4_ifvaln([$3], [else $3])dnl fi]) # _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) # --------------------------------------------- m4_define([_PKG_CONFIG], [if test -n "$$1"; then pkg_cv_[]$1="$$1" elif test -n "$PKG_CONFIG"; then PKG_CHECK_EXISTS([$3], [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`], [pkg_failed=yes]) else pkg_failed=untried fi[]dnl ])# _PKG_CONFIG # _PKG_SHORT_ERRORS_SUPPORTED # ----------------------------- AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], [AC_REQUIRE([PKG_PROG_PKG_CONFIG]) if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi[]dnl ])# _PKG_SHORT_ERRORS_SUPPORTED # PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], # [ACTION-IF-NOT-FOUND]) # # # Note that if there is a possibility the first call to # PKG_CHECK_MODULES might not happen, you should be sure to include an # explicit call to PKG_PROG_PKG_CONFIG in your configure.ac # # # -------------------------------------------------------------- AC_DEFUN([PKG_CHECK_MODULES], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl pkg_failed=no AC_MSG_CHECKING([for $1]) _PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) _PKG_CONFIG([$1][_LIBS], [libs], [$2]) m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS and $1[]_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details.]) if test $pkg_failed = yes; then _PKG_SHORT_ERRORS_SUPPORTED if test $_pkg_short_errors_supported = yes; then $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "$2" 2>&1` else $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors "$2" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD ifelse([$4], , [AC_MSG_ERROR(dnl [Package requirements ($2) were not met: $$1_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. _PKG_TEXT ])], [AC_MSG_RESULT([no]) $4]) elif test $pkg_failed = untried; then ifelse([$4], , [AC_MSG_FAILURE(dnl [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. _PKG_TEXT To get pkg-config, see .])], [$4]) else $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS $1[]_LIBS=$pkg_cv_[]$1[]_LIBS AC_MSG_RESULT([yes]) ifelse([$3], , :, [$3]) fi[]dnl ])# PKG_CHECK_MODULES # Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # # 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. # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.10' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. m4_if([$1], [1.10.2], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) # _AM_AUTOCONF_VERSION(VERSION) # ----------------------------- # aclocal traces this macro to find the Autoconf version. # This is a private macro too. Using m4_define simplifies # the logic in aclocal, which can simply ignore this definition. m4_define([_AM_AUTOCONF_VERSION], []) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.10.2])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. # # 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. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to # `$srcdir', `$srcdir/..', or `$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is `.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [dnl Rely on autoconf to set up CDPATH properly. AC_PREREQ([2.50])dnl # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006 # Free Software Foundation, Inc. # # 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. # serial 8 # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ(2.52)dnl ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl _AM_SUBST_NOTMAKE([$1_FALSE])dnl if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 # Free Software Foundation, Inc. # # 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. # serial 9 # There are a few dirty hacks below to avoid letting `AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "GCJ", or "OBJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl ifelse([$1], CC, [depcc="$CC" am_compiler_list=], [$1], CXX, [depcc="$CXX" am_compiler_list=], [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], UPC, [depcc="$UPC" am_compiler_list=], [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf case $depmode in nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; none) break ;; esac # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. if depmode=$depmode \ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE(dependency-tracking, [ --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 # Free Software Foundation, Inc. # # 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. #serial 4 # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [# Autoconf 2.62 quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named `Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running `make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` AS_MKDIR_P([$dirpart/$fdir]) # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking # is enabled. FIXME. This creates each `.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) # Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 # Free Software Foundation, Inc. # # 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. # serial 8 # AM_CONFIG_HEADER is obsolete. It has been replaced by AC_CONFIG_HEADERS. AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005, 2006, 2008 Free Software Foundation, Inc. # # 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. # serial 13 # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.60])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl # test to see if srcdir already configured if test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) AM_MISSING_PROG(AUTOCONF, autoconf) AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) AM_MISSING_PROG(AUTOHEADER, autoheader) AM_MISSING_PROG(MAKEINFO, makeinfo) AM_PROG_INSTALL_SH AM_PROG_INSTALL_STRIP AC_REQUIRE([AM_PROG_MKDIR_P])dnl # We need awk for the "check" target. The system "awk" is bad on # some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES(CC)], [define([AC_PROG_CC], defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES(CXX)], [define([AC_PROG_CXX], defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES(OBJC)], [define([AC_PROG_OBJC], defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl ]) ]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. # # 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. # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl install_sh=${install_sh-"\$(SHELL) $am_aux_dir/install-sh"} AC_SUBST(install_sh)]) # Copyright (C) 2003, 2005 Free Software Foundation, Inc. # # 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. # serial 2 # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. # # 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. # serial 3 # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. AC_DEFUN([AM_MAKE_INCLUDE], [am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo done .PHONY: am__doit END # If we don't find an include directive, just comment out the code. AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # We grep out `Entering directory' and `Leaving directory' # messages which can occur if `w' ends up in MAKEFLAGS. # In particular we don't look at `^make:' because GNU make might # be invoked under some other name (usually "gmake"), in which # case it prints its new name instead of `make'. if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then am__include=include am__quote= _am_result=GNU fi # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then am__include=.include am__quote="\"" _am_result=BSD fi fi AC_SUBST([am__include]) AC_SUBST([am__quote]) AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) # Copyright (C) 1999, 2000, 2001, 2003, 2004, 2005, 2008 # Free Software Foundation, Inc. # # 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. # serial 6 # AM_PROG_CC_C_O # -------------- # Like AC_PROG_CC_C_O, but changed for automake. AC_DEFUN([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC_C_O])dnl AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([compile])dnl # FIXME: we rely on the cache variable name because # there is no other way. set dummy $CC am_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']` eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o if test "$am_t" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi dnl Make sure AC_PROG_CC is never called again, or it will override our dnl setting of CC. m4_define([AC_PROG_CC], [m4_fatal([AC_PROG_CC cannot be called after AM_PROG_CC_C_O])]) ]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005 # Free Software Foundation, Inc. # # 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. # serial 5 # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it supports --run. # If it does, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= AC_MSG_WARN([`missing' script is too old or missing]) fi ]) # Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. # # 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. # AM_PROG_MKDIR_P # --------------- # Check for `mkdir -p'. AC_DEFUN([AM_PROG_MKDIR_P], [AC_PREREQ([2.60])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, dnl while keeping a definition of mkdir_p for backward compatibility. dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of dnl Makefile.ins that do not define MKDIR_P, so we do our own dnl adjustment using top_builddir (which is defined more often than dnl MKDIR_P). AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl case $mkdir_p in [[\\/$]]* | ?:[[\\/]]*) ;; */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; esac ]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001, 2002, 2003, 2005, 2008 Free Software Foundation, Inc. # # 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. # serial 4 # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # ------------------------------ # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), 1)]) # _AM_SET_OPTIONS(OPTIONS) # ---------------------------------- # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 # Free Software Foundation, Inc. # # 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. # serial 4 # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Just in case sleep 1 echo timestamp > conftest.file # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t $srcdir/configure conftest.file` fi rm -f conftest.file if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT(yes)]) # Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. # # 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. # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor `install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in `make install-strip', and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be `maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Copyright (C) 2006 Free Software Foundation, Inc. # # 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. # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. # This macro is traced by Automake. AC_DEFUN([_AM_SUBST_NOTMAKE]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004, 2005 Free Software Foundation, Inc. # # 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. # serial 2 # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of `v7', `ustar', or `pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. AM_MISSING_PROG([AMTAR], [tar]) m4_if([$1], [v7], [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], [m4_case([$1], [ustar],, [pax],, [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' _am_tools=${am_cv_prog_tar_$1-$_am_tools} # Do not fold the above two line into one, because Tru64 sh and # Solaris sh will not grok spaces in the rhs of `-'. for _am_tool in $_am_tools do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR aqualung-0.9beta11/Makefile.am0000644000175000001440000000106510701710463013147 00000000000000SUBDIRS = doc skin . src EXTRA_DIST = autogen.sh ladspa.h all-local: cd src; \ if test -e version.h; then svn1="`cat version.h`"; else svn1=""; fi; \ if test -e ../.svn; then svn2="#define AQUALUNG_VERSION \"R-`cd ..; LC_ALL=C svn info | grep '^Revision' | awk '{print $$2}'`\""; else svn2=""; fi; \ if test "$$svn1" -a "$$svn2" -a "$$svn1" != "$$svn2" -o -z "$$svn1" -a "$$svn2"; then echo "$$svn2" > version.h; fi; \ if test -z "$$svn1" -a -z "$$svn2"; then echo "#define AQUALUNG_VERSION \"R-???\"" > version.h; fi; uninstall-local: rm -rf $(pkgdatadir) aqualung-0.9beta11/Makefile.in0000644000175000001440000004655111331334254013171 00000000000000# Makefile.in generated by automake 1.10.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # This Makefile.in 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. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = . DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in $(srcdir)/config.h.in \ $(top_srcdir)/configure AUTHORS COPYING ChangeLog INSTALL NEWS \ compile depcomp install-sh missing mkinstalldirs ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ install-html-recursive install-info-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ { test ! -d $(distdir) \ || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -fr $(distdir); }; } DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best distuninstallcheck_listfiles = find . -type f -print distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBAVCODEC_CFLAGS = @LIBAVCODEC_CFLAGS@ LIBAVCODEC_LIBS = @LIBAVCODEC_LIBS@ LIBAVFORMAT_CFLAGS = @LIBAVFORMAT_CFLAGS@ LIBAVFORMAT_LIBS = @LIBAVFORMAT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ var = @var@ SUBDIRS = doc skin . src EXTRA_DIST = autogen.sh ladspa.h all: config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: am--refresh: @: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --gnu '; \ cd $(srcdir) && $(AUTOMAKE) --gnu \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: $(am__configure_deps) cd $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) config.h: stamp-h1 @if test ! -f $@; then \ rm -f stamp-h1; \ $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \ else :; fi stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status config.h $(srcdir)/config.h.in: $(am__configure_deps) cd $(top_srcdir) && $(AUTOHEADER) rm -f stamp-h1 touch $@ distclean-hdr: -rm -f config.h stamp-h1 # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) $(am__remove_distdir) test -d $(distdir) || mkdir $(distdir) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ distdir=`$(am__cd) $(distdir) && pwd`; \ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ (cd $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$top_distdir" \ distdir="$$distdir/$$subdir" \ am__remove_distdir=: \ am__skip_length_check=: \ distdir) \ || exit 1; \ fi; \ done -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r $(distdir) dist-gzip: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 $(am__remove_distdir) dist-lzma: distdir tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma $(am__remove_distdir) dist-tarZ: distdir tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__remove_distdir) dist-shar: distdir shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__remove_distdir) dist dist-all: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lzma*) \ unlzma -c $(distdir).tar.lzma | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir); chmod a+w $(distdir) mkdir $(distdir)/_build mkdir $(distdir)/_inst chmod a-w $(distdir) dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && cd $(distdir)/_build \ && ../configure --srcdir=.. --prefix="$$dc_install_base" \ $(DISTCHECK_CONFIGURE_FLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck $(am__remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: @cd $(distuninstallcheck_dir) \ && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am check: check-recursive all-am: Makefile config.h all-local installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -f Makefile distclean-am: clean-am distclean-generic distclean-hdr distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-exec-am: install-html: install-html-recursive install-info: install-info-recursive install-man: install-pdf: install-pdf-recursive install-ps: install-ps-recursive installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-local .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \ install-strip .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am all-local am--refresh check check-am clean \ clean-generic ctags ctags-recursive dist dist-all dist-bzip2 \ dist-gzip dist-lzma dist-shar dist-tarZ dist-zip distcheck \ distclean distclean-generic distclean-hdr distclean-tags \ distcleancheck distdir distuninstallcheck dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \ uninstall-local all-local: cd src; \ if test -e version.h; then svn1="`cat version.h`"; else svn1=""; fi; \ if test -e ../.svn; then svn2="#define AQUALUNG_VERSION \"R-`cd ..; LC_ALL=C svn info | grep '^Revision' | awk '{print $$2}'`\""; else svn2=""; fi; \ if test "$$svn1" -a "$$svn2" -a "$$svn1" != "$$svn2" -o -z "$$svn1" -a "$$svn2"; then echo "$$svn2" > version.h; fi; \ if test -z "$$svn1" -a -z "$$svn2"; then echo "#define AQUALUNG_VERSION \"R-???\"" > version.h; fi; uninstall-local: rm -rf $(pkgdatadir) # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: aqualung-0.9beta11/config.h.in0000644000175000001440000001475411331330107013140 00000000000000/* config.h.in. Generated from configure.ac by autoheader. */ /* Defined if doing a debug build */ #undef DEBUG_BUILD /* Defined if compile with ALSA support */ #undef HAVE_ALSA /* Define to 1 if you have the header file. */ #undef HAVE_AVCODEC_H /* Define to 1 if you have the header file. */ #undef HAVE_AVFORMAT_H /* Defined if compile with CDDA support */ #undef HAVE_CDDA /* Defined if compile with CDDB support */ #undef HAVE_CDDB /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H /* Define to 1 if you have the header file. */ #undef HAVE_ERRNO_H /* Define to 1 if you have the header file. */ #undef HAVE_FCNTL_H /* Define to 1 if you have the header file. */ #undef HAVE_FFMPEG_AVCODEC_H /* Define to 1 if you have the header file. */ #undef HAVE_FFMPEG_AVFORMAT_H /* Define to 1 if you have the header file. */ #undef HAVE_FFMPEG_LIBAVCODEC_AVCODEC_H /* Define to 1 if you have the header file. */ #undef HAVE_FFMPEG_LIBAVFORMAT_AVFORMAT_H /* Defined if compile with some kind of FLAC support */ #undef HAVE_FLAC /* Defined if compile with FLAC (1.1.2 and older API) */ #undef HAVE_FLAC_7 /* Defined if compile with FLAC (1.1.3 and newer API) */ #undef HAVE_FLAC_8 /* Define to 1 if you have the `floor' function. */ #undef HAVE_FLOOR /* Defined if compile with iRiver iFP driver support */ #undef HAVE_IFP /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Defined if compile with JACK support */ #undef HAVE_JACK /* Defined if compile with LADSPA plugin support */ #undef HAVE_LADSPA /* Defined if compile with LAME support */ #undef HAVE_LAME /* Defined if compile with LAVC support */ #undef HAVE_LAVC /* Define to 1 if you have the header file. */ #undef HAVE_LIBAVCODEC_AVCODEC_H /* Define to 1 if you have the header file. */ #undef HAVE_LIBAVFORMAT_AVFORMAT_H /* Defined if compile with libbz2 */ #undef HAVE_LIBBZ2 /* Define to 1 if you have the `dl' library (-ldl). */ #undef HAVE_LIBDL /* Define to 1 if you have the `pthread' library (-lpthread). */ #undef HAVE_LIBPTHREAD /* Define to 1 if you have the `xml2' library (-lxml2). */ #undef HAVE_LIBXML2 /* Defined if compile with libz */ #undef HAVE_LIBZ /* Defined if version(GTK+-2.0) >= 2.8 */ #undef HAVE_LOOP /* Defined if compiled with Lua support */ #undef HAVE_LUA /* Defined if compile with Monkey's Audio Codec support */ #undef HAVE_MAC /* Define to 1 if your system has a GNU libc compatible `malloc' function, and to 0 otherwise. */ #undef HAVE_MALLOC /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the `memset' function. */ #undef HAVE_MEMSET /* Define to 1 if you have the `mkdir' function. */ #undef HAVE_MKDIR /* Defined if compile with MOD Audio support */ #undef HAVE_MOD /* Defined if version(libmodplug) >= 0.8 */ #undef HAVE_MOD_INFO /* Defined if compile with Musepack support */ #undef HAVE_MPC /* Defined if compile with MPEG Audio support */ #undef HAVE_MPEG /* Defined if compile with Ogg Vorbis support */ #undef HAVE_OGG_VORBIS /* Defined if compile with OSS support */ #undef HAVE_OSS /* Defined if compile with podcast support */ #undef HAVE_PODCAST /* Defined if compile with PulseAudio support */ #undef HAVE_PULSE /* Defined if compile with sndfile (WAV, AIFF, etc.) support */ #undef HAVE_SNDFILE /* Defined if version(sndfile) >= 1.0.12 */ #undef HAVE_SNDFILE_1_0_12 /* Defined if version(sndfile) >= 1.0.18 */ #undef HAVE_SNDFILE_1_0_18 /* Defined if compile with sndio support */ #undef HAVE_SNDIO /* Defined if compile with Ogg Speex support */ #undef HAVE_SPEEX /* Defined if compile with Sample Rate Converter support */ #undef HAVE_SRC /* Define to 1 if `stat' has the bug that it succeeds when given the zero-length file name argument. */ #undef HAVE_STAT_EMPTY_STRING_BUG /* 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 `strcasestr' function. */ #undef HAVE_STRCASESTR /* Define to 1 if you have the `strdup' function. */ #undef HAVE_STRDUP /* 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 `strndup' function. */ #undef HAVE_STRNDUP /* Define to 1 if you have the `strrchr' function. */ #undef HAVE_STRRCHR /* Define to 1 if you have the `strstr' function. */ #undef HAVE_STRSTR /* Defined if version(GTK+-2.0) >= 2.10 */ #undef HAVE_SYSTRAY /* Define to 1 if you have the header file. */ #undef HAVE_SYS_IOCTL_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 /* Defined if compile with Ogg Vorbis encoding support */ #undef HAVE_VORBISENC /* Defined if compile with Wavpack support */ #undef HAVE_WAVPACK /* Defined if libcddb handles disc revision number */ #undef LIBCDDB_REVISION /* Define to 1 if `lstat' dereferences a symlink specified with a trailing slash. */ #undef LSTAT_FOLLOWS_SLASHED_SYMLINK /* Defined if lua headers detected in a nonstandard location */ #undef LUA_HEADER_lua5_1 /* Defined if old Musepack API is used */ #undef MPC_OLD_API /* Define to 1 if your C compiler doesn't accept -c and -o together. */ #undef NO_MINUS_C_MINUS_O /* 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 version of this package. */ #undef PACKAGE_VERSION /* Defined if doing a release build */ #undef RELEASE_BUILD /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Version number of package */ #undef VERSION /* Define to empty if `const' does not conform to ANSI C. */ #undef const /* Define to rpl_malloc if the replacement function should be used. */ #undef malloc /* Define to `unsigned int' if does not define. */ #undef size_t aqualung-0.9beta11/configure0000755000175000001440000140330211331330032013011 00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.63 for aqualung 0.9beta11. # # Report bugs to . # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## --------------------- ## ## 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 # PATH needs CR # 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_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 if (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 # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false 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. 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); exit 1; } fi # Work around bugs in pre-3.0 UWIN ksh. for as_var in ENV MAIL MAILPATH do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # Required to use basename. 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 # Name of the executable. 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'` # CDPATH. $as_unset CDPATH if test "x$CONFIG_SHELL" = x; then if (eval ":") 2>/dev/null; then as_have_required=yes else as_have_required=no fi if test $as_have_required = yes && (eval ": (as_func_return () { (exit \$1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = \"\$1\" ); then : else exitcode=1 echo positional parameters were not saved. fi test \$exitcode = 0) || { (exit 1); exit 1; } ( as_lineno_1=\$LINENO as_lineno_2=\$LINENO test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } ") 2> /dev/null; then : else as_candidate_shells= as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. case $as_dir in /*) for as_base in sh bash ksh sh5; do as_candidate_shells="$as_candidate_shells $as_dir/$as_base" done;; esac done IFS=$as_save_IFS for as_shell in $as_candidate_shells $SHELL; do # Try only shells that exist, to save several forks. if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { ("$as_shell") 2> /dev/null <<\_ASEOF 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 : _ASEOF }; then CONFIG_SHELL=$as_shell as_have_required=yes if { "$as_shell" 2> /dev/null <<\_ASEOF 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_func_return () { (exit $1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = "$1" ); then : else exitcode=1 echo positional parameters were not saved. fi test $exitcode = 0) || { (exit 1); exit 1; } ( as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } _ASEOF }; then break fi fi done if test "x$CONFIG_SHELL" != x; then for as_var in BASH_ENV ENV do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done export CONFIG_SHELL exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} fi if test $as_have_required = no; then echo This script requires a shell more modern than all the echo shells that I found on your system. Please install a echo modern shell, or manually run the script under such a echo shell if you do have one. { (exit 1); exit 1; } fi fi fi (eval "as_func_return () { (exit \$1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = \"\$1\" ); then : else exitcode=1 echo positional parameters were not saved. fi test \$exitcode = 0") || { echo No shell found that supports shell functions. echo Please tell bug-autoconf@gnu.org about your system, echo including any error possibly output before this message. echo This can help us improve future autoconf versions. echo Configuration will now proceed without shell functions. } as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line after each line using $LINENO; the second 'sed' # does the real work. The second script uses 'N' to pair each # line-number line with the line containing $LINENO, and appends # trailing '-' during substitution so that $LINENO is not a special # case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # scripts with optimization help from Paolo Bonzini. 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 { (exit 1); exit 1; }; } # 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 } if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in -n*) case `echo 'x\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. *) ECHO_C='\c';; esac;; *) ECHO_N='-n';; esac if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi 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 -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' 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=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # 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 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, 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= SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME='aqualung' PACKAGE_TARNAME='aqualung' PACKAGE_VERSION='0.9beta11' PACKAGE_STRING='aqualung 0.9beta11' PACKAGE_BUGREPORT='http://aqualung.factorial.hu/mantis' ac_unique_file="src/core.c" # 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" ac_subst_vars='LTLIBOBJS LIBAVFORMAT_LIBS LIBAVFORMAT_CFLAGS LIBAVCODEC_LIBS LIBAVCODEC_CFLAGS PKG_CONFIG var LIBOBJS EGREP GREP CPP am__fastdepCXX_FALSE am__fastdepCXX_TRUE CXXDEPMODE ac_ct_CXX CXXFLAGS CXX RANLIB am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE am__quote am__include DEPDIR OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC am__untar am__tar AMTAR am__leading_dot SET_MAKE AWK mkdir_p MKDIR_P INSTALL_STRIP_PROGRAM STRIP install_sh MAKEINFO AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL VERSION PACKAGE CYGPATH_W am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM 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_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_debug enable_dependency_tracking with_sndio with_oss with_alsa with_jack with_pulse with_src with_sndfile with_flac with_ogg with_vorbisenc with_speex with_mpeg with_mod with_mpc with_mac with_lavc with_lame with_wavpack with_ladspa with_cdda with_cddb with_ifp with_systray with_loop with_podcast with_lua ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CXX CXXFLAGS CCC CPP PKG_CONFIG LIBAVCODEC_CFLAGS LIBAVCODEC_LIBS LIBAVFORMAT_CFLAGS LIBAVFORMAT_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=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_echo "$as_me: error: invalid feature name: $ac_useropt" >&2 { (exit 1); exit 1; }; } 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_echo "$as_me: error: invalid feature name: $ac_useropt" >&2 { (exit 1); exit 1; }; } 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_echo "$as_me: error: invalid package name: $ac_useropt" >&2 { (exit 1); exit 1; }; } 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_echo "$as_me: error: invalid package name: $ac_useropt" >&2 { (exit 1); exit 1; }; } 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_echo "$as_me: error: unrecognized option: $ac_option Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && { $as_echo "$as_me: error: invalid variable name: $ac_envvar" >&2 { (exit 1); exit 1; }; } 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_echo "$as_me: error: missing argument to $ac_option" >&2 { (exit 1); exit 1; }; } fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) { $as_echo "$as_me: error: unrecognized options: $ac_unrecognized_opts" >&2 { (exit 1); exit 1; }; } ;; *) $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_echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; } 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 $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used." >&2 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_echo "$as_me: error: working directory cannot be determined" >&2 { (exit 1); exit 1; }; } test "X$ac_ls_di" = "X$ac_pwd_ls_di" || { $as_echo "$as_me: error: pwd does not report name of working directory" >&2 { (exit 1); exit 1; }; } # 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_echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 { (exit 1); exit 1; }; } fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || { $as_echo "$as_me: error: $ac_msg" >&2 { (exit 1); exit 1; }; } 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 aqualung 0.9beta11 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/aqualung] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of aqualung 0.9beta11:";; 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] --enable-debug=yes,no compile with debugging support (default: no) --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-sndio=no,yes compile with sndio support (default: no) --with-oss=yes,no compile with OSS support (default: yes) --with-alsa=yes,no compile with ALSA support (default: yes) --with-jack=yes,no compile with JACK support (default: yes) --with-pulse=yes,no compile with PulseAudio support (default: yes) --with-src=yes,no compile with Sample Rate Converter support (default: yes) --with-sndfile=yes,no compile with sndfile (WAV, AIFF, etc.) support (default: yes) --with-flac=yes,no compile with FLAC support (default: yes) --with-ogg=yes,no compile with Ogg Vorbis support (default: yes) --with-vorbisenc=yes,no compile with Ogg Vorbis encoding support (default: yes) --with-speex=yes,no compile with Ogg Speex support (default: yes) --with-mpeg=yes,no compile with MPEG Audio support (default: yes) --with-mod=yes,no compile with MOD Audio support (default: yes) --with-mpc=yes,no compile with Musepack support (default: yes) --with-mac=yes,no compile with Monkey's Audio Codec support (default: yes) --with-lavc=yes,no compile with lavc (FFmpeg) support (default: yes) --with-lame=yes,no compile with LAME (MP3 encoding) support (default: yes) --with-wavpack=yes,no compile with WavPack support (default: yes) --with-ladspa=yes,no compile with LADSPA plugin support (default: yes) --with-cdda=yes,no compile with CDDA support (default: yes) --with-cddb=yes,no compile with CDDB support (default: yes) --with-ifp=yes,no compile with iRiver iFP driver support (default: yes) --with-systray=yes,no compile with Systray support (default: yes) --with-loop=yes,no compile with loop playback support (default: yes) --with-podcast=yes,no compile with podcast support (default: yes) --with-lua=yes,no compile with Lua (programmable title formatting) support (default: yes) 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 C/C++/Objective 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 PKG_CONFIG path to pkg-config utility LIBAVCODEC_CFLAGS C compiler flags for LIBAVCODEC, overriding pkg-config LIBAVCODEC_LIBS linker flags for LIBAVCODEC, overriding pkg-config LIBAVFORMAT_CFLAGS C compiler flags for LIBAVFORMAT, overriding pkg-config LIBAVFORMAT_LIBS linker flags for LIBAVFORMAT, 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 . _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 aqualung configure 0.9beta11 generated by GNU Autoconf 2.63 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi 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 aqualung $as_me 0.9beta11, which was generated by GNU Autoconf 2.63. 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) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; 2) ac_configure_args1="$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 ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac done done $as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } $as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export 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 cat <<\_ASBOX ## ---------------- ## ## Cache variables. ## ## ---------------- ## _ASBOX 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:$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= ;; #( *) $as_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 cat <<\_ASBOX ## ----------------- ## ## Output variables. ## ## ----------------- ## _ASBOX 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 cat <<\_ASBOX ## ------------------- ## ## File substitutions. ## ## ------------------- ## _ASBOX 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 cat <<\_ASBOX ## ----------- ## ## confdefs.h. ## ## ----------- ## _ASBOX 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'; { (exit 1); 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 # 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 # 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 ac_site_file1=$CONFIG_SITE 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 -r "$ac_site_file"; then { $as_echo "$as_me:$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" 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. if test -f "$cache_file"; then { $as_echo "$as_me:$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:$LINENO: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # 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:$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:$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:$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:$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:$LINENO: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:$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. *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:$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_echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 $as_echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} { (exit 1); exit 1; }; } 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 am__api_version='1.10' ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; 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_echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5 $as_echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;} { (exit 1); exit 1; }; } 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. # 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:$LINENO: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; 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 { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$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:$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:$LINENO: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } # Just in case sleep 1 echo timestamp > conftest.file # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t $srcdir/configure conftest.file` fi rm -f conftest.file if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". { { $as_echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken alias in your environment" >&5 $as_echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken alias in your environment" >&2;} { (exit 1); exit 1; }; } fi test "$2" = conftest.file ) then # Ok. : else { { $as_echo "$as_me:$LINENO: error: newly created file is older than distributed files! Check your system clock" >&5 $as_echo "$as_me: error: newly created file is older than distributed files! Check your system clock" >&2;} { (exit 1); exit 1; }; } fi { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= { $as_echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5 $as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} fi { $as_echo "$as_me:$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 test "${ac_cv_path_mkdir+set}" = set; 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 { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$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 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. test -d ./--version && rmdir ./--version MKDIR_P="$ac_install_sh -d" fi fi { $as_echo "$as_me:$LINENO: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } mkdir_p="$MKDIR_P" case $mkdir_p in [\\/$]* | ?:[\\/]*) ;; */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; esac for ac_prog in gawk mawk nawk awk 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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_AWK+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:$LINENO: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done { $as_echo "$as_me:$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 { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; 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:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then { { $as_echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5 $as_echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;} { (exit 1); exit 1; }; } fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE=aqualung VERSION=0.9beta11 cat >>confdefs.h <<_ACEOF #define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF #define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} install_sh=${install_sh-"\$(SHELL) $am_aux_dir/install-sh"} # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_STRIP+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:$LINENO: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:$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 STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" # We need awk for the "check" target. The system "awk" is bad on # some platforms. # Always define AMTAR for backward compatibility. AMTAR=${AMTAR-"${am_missing_run}tar"} am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' ac_config_headers="$ac_config_headers config.h" { $as_echo "$as_me:$LINENO: checking for type of build" >&5 $as_echo_n "checking for type of build... " >&6; } # Check whether --enable-debug was given. if test "${enable_debug+set}" = set; then enableval=$enable_debug; debug="$enableval" else debug="no" fi if test "$debug" = "yes"; then buildtype=debug BUILD_CFLAGS="-rdynamic -ggdb -g -O0" cat >>confdefs.h <<\_ACEOF #define DEBUG_BUILD 1 _ACEOF { $as_echo "$as_me:$LINENO: result: debug" >&5 $as_echo "debug" >&6; } else buildtype=release BUILD_CFLAGS="-O2" cat >>confdefs.h <<\_ACEOF #define RELEASE_BUILD 1 _ACEOF { $as_echo "$as_me:$LINENO: result: release" >&5 $as_echo "release" >&6; } fi { $as_echo "$as_me:$LINENO: checking for compilation platform" >&5 $as_echo_n "checking for compilation platform... " >&6; } if test `uname -a | grep CYGWIN | wc -l` = "1" ; then PLATFORM_CFLAGS="-mwin32 -mwindows" PLATFORM_LIBS="-lintl -lwinmm" win32="yes" freebsd="no" openbsd="no" linux="no" if test "$buildtype" = "debug"; then { { $as_echo "$as_me:$LINENO: error: Sorry, debug build under Cygwin is unsupported!" >&5 $as_echo "$as_me: error: Sorry, debug build under Cygwin is unsupported!" >&2;} { (exit 1); exit 1; }; } fi platform="Cygwin" { $as_echo "$as_me:$LINENO: result: Cygwin" >&5 $as_echo "Cygwin" >&6; } fi if test `uname -a | grep FreeBSD | wc -l` = "1" ; then PLATFORM_CFLAGS="" PLATFORM_LIBS="" win32="no" freebsd="yes" openbsd="no" linux="no" if test "$buildtype" = "debug"; then { { $as_echo "$as_me:$LINENO: error: Sorry, debug build under FreeBSD is unsupported!" >&5 $as_echo "$as_me: error: Sorry, debug build under FreeBSD is unsupported!" >&2;} { (exit 1); exit 1; }; } fi platform="FreeBSD" { $as_echo "$as_me:$LINENO: result: FreeBSD" >&5 $as_echo "FreeBSD" >&6; } fi if test `uname -a | grep OpenBSD | wc -l` = "1" ; then PLATFORM_CFLAGS="" PLATFORM_LIBS="" win32="no" freebsd="no" openbsd="yes" linux="no" if test "$buildtype" = "debug"; then { { $as_echo "$as_me:$LINENO: error: Sorry, debug build under OpenBSD is unsupported!" >&5 $as_echo "$as_me: error: Sorry, debug build under OpenBSD is unsupported!" >&2;} { (exit 1); exit 1; }; } fi platform="OpenBSD" { $as_echo "$as_me:$LINENO: result: OpenBSD" >&5 $as_echo "OpenBSD" >&6; } fi if test `uname -a | grep Linux | wc -l` = "1" ; then PLATFORM_CFLAGS="" PLATFORM_LIBS="" win32="no" freebsd="no" openbsd="no" linux="yes" platform="Linux" { $as_echo "$as_me:$LINENO: result: Linux" >&5 $as_echo "Linux" >&6; } fi # Checks for programs. 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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:$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:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:$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:$LINENO: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:$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:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:$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:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$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:$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:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:$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:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:$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:$LINENO: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:$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:$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:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&5 $as_echo "$as_me: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } # Provide some information about the compiler. $as_echo "$as_me:$LINENO: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 { (ac_try="$ac_compiler --version >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler --version >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -v >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler -v >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -V >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler -V >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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:$LINENO: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; 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 { $as_echo "$as_me:$LINENO: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } if test -z "$ac_file"; then $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: C compiler cannot create executables See \`config.log' for more details." >&5 $as_echo "$as_me: error: C compiler cannot create executables See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; }; } fi ac_exeext=$ac_cv_exeext # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:$LINENO: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } # FIXME: These cross compiler hacks should be removed for Autoconf 3.0 # If not cross compiling, check that we can run a simple program. if test "$cross_compiling" != yes; then if { ac_try='./$ac_file' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&5 $as_echo "$as_me: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } fi fi fi { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } { $as_echo "$as_me:$LINENO: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } { $as_echo "$as_me:$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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; 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:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&5 $as_echo "$as_me: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } fi rm -f conftest$ac_cv_exeext { $as_echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT { $as_echo "$as_me:$LINENO: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if test "${ac_cv_objext+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; 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:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&5 $as_echo "$as_me: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:$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 test "${ac_cv_c_compiler_gnu+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_compiler_gnu=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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:$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:$LINENO: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if test "${ac_cv_prog_cc_g+set}" = set; 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 CFLAGS="" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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:$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:$LINENO: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if test "${ac_cv_prog_cc_c89+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include /* 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" 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_c89=$ac_arg else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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:$LINENO: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:$LINENO: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac 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 DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo done .PHONY: am__doit END # If we don't find an include directive, just comment out the code. { $as_echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5 $as_echo_n "checking for style of include used by $am_make... " >&6; } am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # We grep out `Entering directory' and `Leaving directory' # messages which can occur if `w' ends up in MAKEFLAGS. # In particular we don't look at `^make:' because GNU make might # be invoked under some other name (usually "gmake"), in which # case it prints its new name instead of `make'. if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then am__include=include am__quote= _am_result=GNU fi # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then am__include=.include am__quote="\"" _am_result=BSD fi fi { $as_echo "$as_me:$LINENO: result: $_am_result" >&5 $as_echo "$_am_result" >&6; } rm -f confinc confmf # Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then enableval=$enable_dependency_tracking; fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi depcc="$CC" am_compiler_list= { $as_echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf case $depmode in nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; none) break ;; esac # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. if depmode=$depmode \ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= 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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_RANLIB+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { $as_echo "$as_me:$LINENO: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { $as_echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 $as_echo "$ac_ct_RANLIB" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:$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_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi 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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CXX+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" $as_echo "$as_me:$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:$LINENO: result: $CXX" >&5 $as_echo "$CXX" >&6; } else { $as_echo "$as_me:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_CXX+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CXX="$ac_prog" $as_echo "$as_me:$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:$LINENO: result: $ac_ct_CXX" >&5 $as_echo "$ac_ct_CXX" >&6; } else { $as_echo "$as_me:$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:$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:$LINENO: checking for C++ compiler version" >&5 set X $ac_compile ac_compiler=$2 { (ac_try="$ac_compiler --version >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler --version >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -v >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler -v >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -V >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler -V >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { $as_echo "$as_me:$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 test "${ac_cv_cxx_compiler_gnu+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_compiler_gnu=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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:$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:$LINENO: checking whether $CXX accepts -g" >&5 $as_echo_n "checking whether $CXX accepts -g... " >&6; } if test "${ac_cv_prog_cxx_g+set}" = set; 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cxx_g=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 CXXFLAGS="" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cxx_g=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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:$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 depcc="$CXX" am_compiler_list= { $as_echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if test "${am_cv_CXX_dependencies_compiler_type+set}" = set; then $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CXX_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf case $depmode in nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; none) break ;; esac # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. if depmode=$depmode \ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CXX_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CXX_dependencies_compiler_type=none fi fi { $as_echo "$as_me:$LINENO: result: $am_cv_CXX_dependencies_compiler_type" >&5 $as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then am__fastdepCXX_TRUE= am__fastdepCXX_FALSE='#' else am__fastdepCXX_TRUE='#' am__fastdepCXX_FALSE= fi if test "x$CC" != xcc; then { $as_echo "$as_me:$LINENO: checking whether $CC and cc understand -c and -o together" >&5 $as_echo_n "checking whether $CC and cc understand -c and -o together... " >&6; } else { $as_echo "$as_me:$LINENO: checking whether cc understands -c and -o together" >&5 $as_echo_n "checking whether cc understands -c and -o together... " >&6; } fi set dummy $CC; ac_cc=`$as_echo "$2" | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` if { as_var=ac_cv_prog_cc_${ac_cc}_c_o; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF # Make sure it works both with $CC and with simple cc. # We do the test twice because some compilers refuse to overwrite an # existing .o file with -o, though they will create one. ac_try='$CC -c conftest.$ac_ext -o conftest2.$ac_objext >&5' rm -f conftest2.* if { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && test -f conftest2.$ac_objext && { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then eval ac_cv_prog_cc_${ac_cc}_c_o=yes if test "x$CC" != xcc; then # Test first that cc exists at all. if { ac_try='cc -c conftest.$ac_ext >&5' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_try='cc -c conftest.$ac_ext -o conftest2.$ac_objext >&5' rm -f conftest2.* if { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && test -f conftest2.$ac_objext && { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # cc works too. : else # cc exists but doesn't like -o. eval ac_cv_prog_cc_${ac_cc}_c_o=no fi fi fi else eval ac_cv_prog_cc_${ac_cc}_c_o=no fi rm -f core conftest* fi if eval test \$ac_cv_prog_cc_${ac_cc}_c_o = yes; then { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } cat >>confdefs.h <<\_ACEOF #define NO_MINUS_C_MINUS_O 1 _ACEOF fi # FIXME: we rely on the cache variable name because # there is no other way. set dummy $CC am_cc=`echo $2 | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o if test "$am_t" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi # Checks for header files. 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:$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 test "${ac_cv_prog_CPP+set}" = set; 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f 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:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&5 $as_echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } 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:$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 test "${ac_cv_path_GREP+set}" = set; 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" { test -f "$ac_path_GREP" && $as_test_x "$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 ac_count=`expr $ac_count + 1` 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_echo "$as_me:$LINENO: error: no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 $as_echo "$as_me: error: no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} { (exit 1); exit 1; }; } fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:$LINENO: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if test "${ac_cv_path_EGREP+set}" = set; 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" { test -f "$ac_path_EGREP" && $as_test_x "$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 ac_count=`expr $ac_count + 1` 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_echo "$as_me:$LINENO: error: no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 $as_echo "$as_me: error: no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} { (exit 1); exit 1; }; } fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:$LINENO: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if test "${ac_cv_header_stdc+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_header_stdc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 rm -f 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : 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 ( exit $ac_status ) ac_cv_header_stdc=no fi rm -rf conftest.dSYM rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then cat >>confdefs.h <<\_ACEOF #define STDC_HEADERS 1 _ACEOF 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` { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` if test "x$as_val" = x""yes; then cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in errno.h fcntl.h stdlib.h string.h sys/ioctl.h unistd.h dlfcn.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 $as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 $as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## -------------------------------------------------- ## ## Report this to http://aqualung.factorial.hu/mantis ## ## -------------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` if test "x$as_val" = x""yes; then cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done # Checks for typedefs, structures, and compiler characteristics. { $as_echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5 $as_echo_n "checking for an ANSI C-conforming const... " >&6; } if test "${ac_cv_c_const+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { /* FIXME: Include the comments suggested by Paul. */ #ifndef __cplusplus /* Ultrix mips cc rejects this. */ typedef int charset[2]; const charset cs; /* SunOS 4.1.1 cc rejects this. */ char const *const *pcpcc; char **ppc; /* NEC SVR4.0.2 mips cc rejects this. */ struct point {int x, y;}; static struct point const zero = {0,0}; /* AIX XL C 1.02.0.0 rejects this. It does not let you subtract one const X* pointer from another in an arm of an if-expression whose if-part is not a constant expression */ const char *g = "string"; pcpcc = &g + (g ? g-g : 0); /* HPUX 7.0 cc rejects these. */ ++pcpcc; ppc = (char**) pcpcc; pcpcc = (char const *const *) ppc; { /* SCO 3.2v4 cc rejects this. */ char *t; char const *s = 0 ? (char *) 0 : (char const *) 0; *t++ = 0; if (s) return 0; } { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ int x[] = {25, 17}; const int *foo = &x[0]; ++foo; } { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ typedef const int *iptr; iptr p = 0; ++p; } { /* AIX XL C 1.02.0.0 rejects this saying "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ struct s { int j; const int *ap[3]; }; struct s *b; b->j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; if (!foo) return 0; } return !cs[0] && !zero.x; #endif ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_c_const=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_c_const=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 $as_echo "$ac_cv_c_const" >&6; } if test $ac_cv_c_const = no; then cat >>confdefs.h <<\_ACEOF #define const /**/ _ACEOF fi { $as_echo "$as_me:$LINENO: checking for size_t" >&5 $as_echo_n "checking for size_t... " >&6; } if test "${ac_cv_type_size_t+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_type_size_t=no cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { if (sizeof (size_t)) return 0; ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { if (sizeof ((size_t))) return 0; ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_size_t=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5 $as_echo "$ac_cv_type_size_t" >&6; } if test "x$ac_cv_type_size_t" = x""yes; then : else cat >>confdefs.h <<_ACEOF #define size_t unsigned int _ACEOF fi # Checks for library functions. if test $ac_cv_c_compiler_gnu = yes; then { $as_echo "$as_me:$LINENO: checking whether $CC needs -traditional" >&5 $as_echo_n "checking whether $CC needs -traditional... " >&6; } if test "${ac_cv_prog_gcc_traditional+set}" = set; then $as_echo_n "(cached) " >&6 else ac_pattern="Autoconf.*'x'" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include Autoconf TIOCGETP _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "$ac_pattern" >/dev/null 2>&1; then ac_cv_prog_gcc_traditional=yes else ac_cv_prog_gcc_traditional=no fi rm -f conftest* if test $ac_cv_prog_gcc_traditional = no; then cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include Autoconf TCGETA _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "$ac_pattern" >/dev/null 2>&1; then ac_cv_prog_gcc_traditional=yes fi rm -f conftest* fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_prog_gcc_traditional" >&5 $as_echo "$ac_cv_prog_gcc_traditional" >&6; } if test $ac_cv_prog_gcc_traditional = yes; then CC="$CC -traditional" fi fi for ac_header in stdlib.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 $as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 $as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## -------------------------------------------------- ## ## Report this to http://aqualung.factorial.hu/mantis ## ## -------------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` if test "x$as_val" = x""yes; then cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done { $as_echo "$as_me:$LINENO: checking for GNU libc compatible malloc" >&5 $as_echo_n "checking for GNU libc compatible malloc... " >&6; } if test "${ac_cv_func_malloc_0_nonnull+set}" = set; then $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then ac_cv_func_malloc_0_nonnull=no else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #if defined STDC_HEADERS || defined HAVE_STDLIB_H # include #else char *malloc (); #endif int main () { return ! malloc (0); ; return 0; } _ACEOF rm -f 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_malloc_0_nonnull=yes 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 ( exit $ac_status ) ac_cv_func_malloc_0_nonnull=no fi rm -rf conftest.dSYM rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_func_malloc_0_nonnull" >&5 $as_echo "$ac_cv_func_malloc_0_nonnull" >&6; } if test $ac_cv_func_malloc_0_nonnull = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_MALLOC 1 _ACEOF else cat >>confdefs.h <<\_ACEOF #define HAVE_MALLOC 0 _ACEOF case " $LIBOBJS " in *" malloc.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS malloc.$ac_objext" ;; esac cat >>confdefs.h <<\_ACEOF #define malloc rpl_malloc _ACEOF fi { $as_echo "$as_me:$LINENO: checking whether lstat dereferences a symlink specified with a trailing slash" >&5 $as_echo_n "checking whether lstat dereferences a symlink specified with a trailing slash... " >&6; } if test "${ac_cv_func_lstat_dereferences_slashed_symlink+set}" = set; then $as_echo_n "(cached) " >&6 else rm -f conftest.sym conftest.file echo >conftest.file if test "$as_ln_s" = "ln -s" && ln -s conftest.file conftest.sym; then if test "$cross_compiling" = yes; then ac_cv_func_lstat_dereferences_slashed_symlink=no else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { struct stat sbuf; /* Linux will dereference the symlink and fail. That is better in the sense that it means we will not have to compile and use the lstat wrapper. */ return lstat ("conftest.sym/", &sbuf) == 0; ; return 0; } _ACEOF rm -f 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_lstat_dereferences_slashed_symlink=yes 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 ( exit $ac_status ) ac_cv_func_lstat_dereferences_slashed_symlink=no fi rm -rf conftest.dSYM rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi else # If the `ln -s' command failed, then we probably don't even # have an lstat function. ac_cv_func_lstat_dereferences_slashed_symlink=no fi rm -f conftest.sym conftest.file fi { $as_echo "$as_me:$LINENO: result: $ac_cv_func_lstat_dereferences_slashed_symlink" >&5 $as_echo "$ac_cv_func_lstat_dereferences_slashed_symlink" >&6; } test $ac_cv_func_lstat_dereferences_slashed_symlink = yes && cat >>confdefs.h <<_ACEOF #define LSTAT_FOLLOWS_SLASHED_SYMLINK 1 _ACEOF if test $ac_cv_func_lstat_dereferences_slashed_symlink = no; then case " $LIBOBJS " in *" lstat.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS lstat.$ac_objext" ;; esac fi { $as_echo "$as_me:$LINENO: checking whether stat accepts an empty string" >&5 $as_echo_n "checking whether stat accepts an empty string... " >&6; } if test "${ac_cv_func_stat_empty_string_bug+set}" = set; then $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then ac_cv_func_stat_empty_string_bug=yes else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { struct stat sbuf; return stat ("", &sbuf) == 0; ; return 0; } _ACEOF rm -f 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_stat_empty_string_bug=no 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 ( exit $ac_status ) ac_cv_func_stat_empty_string_bug=yes fi rm -rf conftest.dSYM rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_func_stat_empty_string_bug" >&5 $as_echo "$ac_cv_func_stat_empty_string_bug" >&6; } if test $ac_cv_func_stat_empty_string_bug = yes; then case " $LIBOBJS " in *" stat.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS stat.$ac_objext" ;; esac cat >>confdefs.h <<_ACEOF #define HAVE_STAT_EMPTY_STRING_BUG 1 _ACEOF fi for ac_func in floor memset mkdir strdup strrchr strstr strndup strcasestr do as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` { $as_echo "$as_me:$LINENO: checking for $ac_func" >&5 $as_echo_n "checking for $ac_func... " >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* 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 $ac_func (); /* 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_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then eval "$as_ac_var=yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } as_val=`eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` if test "x$as_val" = x""yes; then cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done # 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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_var+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$var"; then ac_cv_prog_var="$var" # 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_var="yes" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_prog_var" && ac_cv_prog_var="no" fi fi var=$ac_cv_prog_var if test -n "$var"; then { $as_echo "$as_me:$LINENO: result: $var" >&5 $as_echo "$var" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi if test ! "$var" = "yes"; then { { $as_echo "$as_me:$LINENO: error: You do not appear to have pkg-config installed" >&5 $as_echo "$as_me: error: You do not appear to have pkg-config installed" >&2;} { (exit 1); exit 1; }; } fi if test $win32 = "no" ; then { $as_echo "$as_me:$LINENO: checking for pthread_create in -lpthread" >&5 $as_echo_n "checking for pthread_create in -lpthread... " >&6; } if test "${ac_cv_lib_pthread_pthread_create+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpthread $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_pthread_pthread_create=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_pthread_pthread_create=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_pthread_pthread_create" >&5 $as_echo "$ac_cv_lib_pthread_pthread_create" >&6; } if test "x$ac_cv_lib_pthread_pthread_create" = x""yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBPTHREAD 1 _ACEOF LIBS="-lpthread $LIBS" else { { $as_echo "$as_me:$LINENO: error: You do not appear to have a usable pthread library" >&5 $as_echo "$as_me: error: You do not appear to have a usable pthread library" >&2;} { (exit 1); exit 1; }; } fi fi if test $win32 = "no" -a $freebsd = "no" -a $openbsd = "no" ; then { $as_echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if test "${ac_cv_lib_dl_dlopen+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_dl_dlopen=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dl_dlopen=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = x""yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBDL 1 _ACEOF LIBS="-ldl $LIBS" else { { $as_echo "$as_me:$LINENO: error: You do not appear to have a usable interface to the dynamic linking loader." >&5 $as_echo "$as_me: error: You do not appear to have a usable interface to the dynamic linking loader." >&2;} { (exit 1); exit 1; }; } fi fi z_LIBS="" { $as_echo "$as_me:$LINENO: checking for gzopen in -lz" >&5 $as_echo_n "checking for gzopen in -lz... " >&6; } if test "${ac_cv_lib_z_gzopen+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lz $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 gzopen (); int main () { return gzopen (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_z_gzopen=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_z_gzopen=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_z_gzopen" >&5 $as_echo "$ac_cv_lib_z_gzopen" >&6; } if test "x$ac_cv_lib_z_gzopen" = x""yes; then lib=yes else lib=no fi if test "$lib" = "yes"; then z_LIBS="-lz" cat >>confdefs.h <<\_ACEOF #define HAVE_LIBZ 1 _ACEOF fi bz2_LIBS="" { $as_echo "$as_me:$LINENO: checking for BZ2_bzopen in -lbz2" >&5 $as_echo_n "checking for BZ2_bzopen in -lbz2... " >&6; } if test "${ac_cv_lib_bz2_BZ2_bzopen+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lbz2 $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 BZ2_bzopen (); int main () { return BZ2_bzopen (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_bz2_BZ2_bzopen=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_bz2_BZ2_bzopen=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_bz2_BZ2_bzopen" >&5 $as_echo "$ac_cv_lib_bz2_BZ2_bzopen" >&6; } if test "x$ac_cv_lib_bz2_BZ2_bzopen" = x""yes; then lib=yes else lib=no fi if test "$lib" = "yes"; then bz2_LIBS="-lbz2" cat >>confdefs.h <<\_ACEOF #define HAVE_LIBBZ2 1 _ACEOF fi # Checks for libraries. { $as_echo "$as_me:$LINENO: checking whether GTK+ version >= 2.6" >&5 $as_echo_n "checking whether GTK+ version >= 2.6... " >&6; } if pkg-config --exists 'gtk+-2.0 >= 2.6'; then gtk_CFLAGS=`pkg-config --cflags gtk+-2.0` gtk_LIBS=`pkg-config --libs gtk+-2.0` glib_CFLAGS=`pkg-config --cflags gthread-2.0` glib_LIBS=`pkg-config --libs gthread-2.0` { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } { { $as_echo "$as_me:$LINENO: error: GTK+ not found or too old (version < 2.6)" >&5 $as_echo "$as_me: error: GTK+ not found or too old (version < 2.6)" >&2;} { (exit 1); exit 1; }; } fi # Extract the first word of "xml2-config", so it can be a program name with args. set dummy xml2-config; ac_word=$2 { $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_var+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$var"; then ac_cv_prog_var="$var" # 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_var="yes" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_prog_var" && ac_cv_prog_var="no" fi fi var=$ac_cv_prog_var if test -n "$var"; then { $as_echo "$as_me:$LINENO: result: $var" >&5 $as_echo "$var" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi if test ! "$var" = "yes"; then { { $as_echo "$as_me:$LINENO: error: You do not appear to have xml2-config installed. This usually means that the libxml2 library is missing or not properly installed on your system. Get libxml2 from http://xmlsoft.org" >&5 $as_echo "$as_me: error: You do not appear to have xml2-config installed. This usually means that the libxml2 library is missing or not properly installed on your system. Get libxml2 from http://xmlsoft.org" >&2;} { (exit 1); exit 1; }; } fi xml_CFLAGS=`xml2-config --cflags` xml_LIBS=`xml2-config --libs` { $as_echo "$as_me:$LINENO: checking for xmlNewDoc in -lxml2" >&5 $as_echo_n "checking for xmlNewDoc in -lxml2... " >&6; } if test "${ac_cv_lib_xml2_xmlNewDoc+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lxml2 $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 xmlNewDoc (); int main () { return xmlNewDoc (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_xml2_xmlNewDoc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_xml2_xmlNewDoc=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_xml2_xmlNewDoc" >&5 $as_echo "$ac_cv_lib_xml2_xmlNewDoc" >&6; } if test "x$ac_cv_lib_xml2_xmlNewDoc" = x""yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBXML2 1 _ACEOF LIBS="-lxml2 $LIBS" else { { $as_echo "$as_me:$LINENO: error: You do not appear to have libxml2 installed. Grab it from http://xmlsoft.org" >&5 $as_echo "$as_me: error: You do not appear to have libxml2 installed. Grab it from http://xmlsoft.org" >&2;} { (exit 1); exit 1; }; } fi { $as_echo "$as_me:$LINENO: checking for sndio support" >&5 $as_echo_n "checking for sndio support... " >&6; } # Check whether --with-sndio was given. if test "${with_sndio+set}" = set; then withval=$with_sndio; sndio="$withval" else sndio="no" fi if test "$oss" = no; then { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } else if test "${ac_cv_header_sndio_h+set}" = set; then { $as_echo "$as_me:$LINENO: checking for sndio.h" >&5 $as_echo_n "checking for sndio.h... " >&6; } if test "${ac_cv_header_sndio_h+set}" = set; then $as_echo_n "(cached) " >&6 fi { $as_echo "$as_me:$LINENO: result: $ac_cv_header_sndio_h" >&5 $as_echo "$ac_cv_header_sndio_h" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking sndio.h usability" >&5 $as_echo_n "checking sndio.h usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking sndio.h presence" >&5 $as_echo_n "checking sndio.h presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { $as_echo "$as_me:$LINENO: WARNING: sndio.h: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: sndio.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: sndio.h: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: sndio.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: sndio.h: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: sndio.h: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: sndio.h: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: sndio.h: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: sndio.h: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: sndio.h: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: sndio.h: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: sndio.h: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: sndio.h: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: sndio.h: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: sndio.h: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: sndio.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## -------------------------------------------------- ## ## Report this to http://aqualung.factorial.hu/mantis ## ## -------------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for sndio.h" >&5 $as_echo_n "checking for sndio.h... " >&6; } if test "${ac_cv_header_sndio_h+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_header_sndio_h=$ac_header_preproc fi { $as_echo "$as_me:$LINENO: result: $ac_cv_header_sndio_h" >&5 $as_echo "$ac_cv_header_sndio_h" >&6; } fi if test "x$ac_cv_header_sndio_h" = x""yes; then hdr=yes else hdr=no fi if test "$hdr" = "yes"; then cat >>confdefs.h <<\_ACEOF #define HAVE_SNDIO 1 _ACEOF if test $openbsd = "yes" ; then { $as_echo "$as_me:$LINENO: checking for sio_open in -lsndio" >&5 $as_echo_n "checking for sio_open in -lsndio... " >&6; } if test "${ac_cv_lib_sndio_sio_open+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsndio $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 sio_open (); int main () { return sio_open (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_sndio_sio_open=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_sndio_sio_open=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_sndio_sio_open" >&5 $as_echo "$ac_cv_lib_sndio_sio_open" >&6; } if test "x$ac_cv_lib_sndio_sio_open" = x""yes; then sndio_LIBS="-lsndio" else sndio_LIBS="" fi else sndio_LIBS="" fi fi if test "$hdr" = "no" -a "$sndio" = "yes"; then { { $as_echo "$as_me:$LINENO: error: You do not appear to have sndio.h needed by sndio sound support." >&5 $as_echo "$as_me: error: You do not appear to have sndio.h needed by sndio sound support." >&2;} { (exit 1); exit 1; }; } fi fi { $as_echo "$as_me:$LINENO: checking for OSS support" >&5 $as_echo_n "checking for OSS support... " >&6; } # Check whether --with-oss was given. if test "${with_oss+set}" = set; then withval=$with_oss; oss="$withval" else oss="detect" fi if test "$oss" = no; then { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } else if test $freebsd = "yes" ; then if test "${ac_cv_header_sys_soundcard_h+set}" = set; then { $as_echo "$as_me:$LINENO: checking for sys/soundcard.h" >&5 $as_echo_n "checking for sys/soundcard.h... " >&6; } if test "${ac_cv_header_sys_soundcard_h+set}" = set; then $as_echo_n "(cached) " >&6 fi { $as_echo "$as_me:$LINENO: result: $ac_cv_header_sys_soundcard_h" >&5 $as_echo "$ac_cv_header_sys_soundcard_h" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking sys/soundcard.h usability" >&5 $as_echo_n "checking sys/soundcard.h usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking sys/soundcard.h presence" >&5 $as_echo_n "checking sys/soundcard.h presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { $as_echo "$as_me:$LINENO: WARNING: sys/soundcard.h: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: sys/soundcard.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: sys/soundcard.h: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: sys/soundcard.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: sys/soundcard.h: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: sys/soundcard.h: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: sys/soundcard.h: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: sys/soundcard.h: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: sys/soundcard.h: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: sys/soundcard.h: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: sys/soundcard.h: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: sys/soundcard.h: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: sys/soundcard.h: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: sys/soundcard.h: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: sys/soundcard.h: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: sys/soundcard.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## -------------------------------------------------- ## ## Report this to http://aqualung.factorial.hu/mantis ## ## -------------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for sys/soundcard.h" >&5 $as_echo_n "checking for sys/soundcard.h... " >&6; } if test "${ac_cv_header_sys_soundcard_h+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_header_sys_soundcard_h=$ac_header_preproc fi { $as_echo "$as_me:$LINENO: result: $ac_cv_header_sys_soundcard_h" >&5 $as_echo "$ac_cv_header_sys_soundcard_h" >&6; } fi if test "x$ac_cv_header_sys_soundcard_h" = x""yes; then hdr=yes else hdr=no fi elif test $openbsd = "yes" ; then if test "${ac_cv_header_soundcard_h+set}" = set; then { $as_echo "$as_me:$LINENO: checking for soundcard.h" >&5 $as_echo_n "checking for soundcard.h... " >&6; } if test "${ac_cv_header_soundcard_h+set}" = set; then $as_echo_n "(cached) " >&6 fi { $as_echo "$as_me:$LINENO: result: $ac_cv_header_soundcard_h" >&5 $as_echo "$ac_cv_header_soundcard_h" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking soundcard.h usability" >&5 $as_echo_n "checking soundcard.h usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking soundcard.h presence" >&5 $as_echo_n "checking soundcard.h presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { $as_echo "$as_me:$LINENO: WARNING: soundcard.h: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: soundcard.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: soundcard.h: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: soundcard.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: soundcard.h: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: soundcard.h: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: soundcard.h: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: soundcard.h: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: soundcard.h: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: soundcard.h: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: soundcard.h: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: soundcard.h: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: soundcard.h: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: soundcard.h: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: soundcard.h: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: soundcard.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## -------------------------------------------------- ## ## Report this to http://aqualung.factorial.hu/mantis ## ## -------------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for soundcard.h" >&5 $as_echo_n "checking for soundcard.h... " >&6; } if test "${ac_cv_header_soundcard_h+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_header_soundcard_h=$ac_header_preproc fi { $as_echo "$as_me:$LINENO: result: $ac_cv_header_soundcard_h" >&5 $as_echo "$ac_cv_header_soundcard_h" >&6; } fi if test "x$ac_cv_header_soundcard_h" = x""yes; then hdr=yes else hdr=no fi elif test $linux = "yes" ; then if test "${ac_cv_header_linux_soundcard_h+set}" = set; then { $as_echo "$as_me:$LINENO: checking for linux/soundcard.h" >&5 $as_echo_n "checking for linux/soundcard.h... " >&6; } if test "${ac_cv_header_linux_soundcard_h+set}" = set; then $as_echo_n "(cached) " >&6 fi { $as_echo "$as_me:$LINENO: result: $ac_cv_header_linux_soundcard_h" >&5 $as_echo "$ac_cv_header_linux_soundcard_h" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking linux/soundcard.h usability" >&5 $as_echo_n "checking linux/soundcard.h usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking linux/soundcard.h presence" >&5 $as_echo_n "checking linux/soundcard.h presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { $as_echo "$as_me:$LINENO: WARNING: linux/soundcard.h: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: linux/soundcard.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: linux/soundcard.h: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: linux/soundcard.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: linux/soundcard.h: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: linux/soundcard.h: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: linux/soundcard.h: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: linux/soundcard.h: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: linux/soundcard.h: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: linux/soundcard.h: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: linux/soundcard.h: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: linux/soundcard.h: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: linux/soundcard.h: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: linux/soundcard.h: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: linux/soundcard.h: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: linux/soundcard.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## -------------------------------------------------- ## ## Report this to http://aqualung.factorial.hu/mantis ## ## -------------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for linux/soundcard.h" >&5 $as_echo_n "checking for linux/soundcard.h... " >&6; } if test "${ac_cv_header_linux_soundcard_h+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_header_linux_soundcard_h=$ac_header_preproc fi { $as_echo "$as_me:$LINENO: result: $ac_cv_header_linux_soundcard_h" >&5 $as_echo "$ac_cv_header_linux_soundcard_h" >&6; } fi if test "x$ac_cv_header_linux_soundcard_h" = x""yes; then hdr=yes else hdr=no fi else hdr="no" { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi if test "$hdr" = "yes"; then cat >>confdefs.h <<\_ACEOF #define HAVE_OSS 1 _ACEOF if test $openbsd = "yes" ; then { $as_echo "$as_me:$LINENO: checking for _oss_ioctl in -lossaudio" >&5 $as_echo_n "checking for _oss_ioctl in -lossaudio... " >&6; } if test "${ac_cv_lib_ossaudio__oss_ioctl+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lossaudio $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 _oss_ioctl (); int main () { return _oss_ioctl (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_ossaudio__oss_ioctl=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_ossaudio__oss_ioctl=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_ossaudio__oss_ioctl" >&5 $as_echo "$ac_cv_lib_ossaudio__oss_ioctl" >&6; } if test "x$ac_cv_lib_ossaudio__oss_ioctl" = x""yes; then oss_LIBS="-lossaudio" else oss_LIBS="" fi else oss_LIBS="" fi fi if test "$hdr" = "no" -a "$oss" = "yes"; then if test $freebsd = "yes" ; then { { $as_echo "$as_me:$LINENO: error: You do not appear to have sys/soundcard.h needed by OSS sound support." >&5 $as_echo "$as_me: error: You do not appear to have sys/soundcard.h needed by OSS sound support." >&2;} { (exit 1); exit 1; }; } elif test $openbsd = "yes" ; then { { $as_echo "$as_me:$LINENO: error: You do not appear to have soundcard.h needed by OSS sound support." >&5 $as_echo "$as_me: error: You do not appear to have soundcard.h needed by OSS sound support." >&2;} { (exit 1); exit 1; }; } elif test $linux = "yes" ; then { { $as_echo "$as_me:$LINENO: error: You do not appear to have linux/soundcard.h needed by OSS sound support." >&5 $as_echo "$as_me: error: You do not appear to have linux/soundcard.h needed by OSS sound support." >&2;} { (exit 1); exit 1; }; } else { { $as_echo "$as_me:$LINENO: error: OSS output is unsupported on current build platform." >&5 $as_echo "$as_me: error: OSS output is unsupported on current build platform." >&2;} { (exit 1); exit 1; }; } fi fi if test "$oss" = "detect"; then oss=$hdr fi fi { $as_echo "$as_me:$LINENO: checking for ALSA support" >&5 $as_echo_n "checking for ALSA support... " >&6; } # Check whether --with-alsa was given. if test "${with_alsa+set}" = set; then withval=$with_alsa; alsa="$withval" else alsa="detect" fi if test "$alsa" = "no"; then { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } else { $as_echo "$as_me:$LINENO: checking for snd_pcm_open in -lasound" >&5 $as_echo_n "checking for snd_pcm_open in -lasound... " >&6; } if test "${ac_cv_lib_asound_snd_pcm_open+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lasound $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 snd_pcm_open (); int main () { return snd_pcm_open (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_asound_snd_pcm_open=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_asound_snd_pcm_open=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_asound_snd_pcm_open" >&5 $as_echo "$ac_cv_lib_asound_snd_pcm_open" >&6; } if test "x$ac_cv_lib_asound_snd_pcm_open" = x""yes; then lib=yes else lib=no fi if test "$lib" = "yes"; then alsa_CFLAGS=`pkg-config --cflags alsa` alsa_LIBS=`pkg-config --libs alsa` cat >>confdefs.h <<\_ACEOF #define HAVE_ALSA 1 _ACEOF fi if test "$lib" = "no" -a "$alsa" = "yes"; then { { $as_echo "$as_me:$LINENO: error: You do not appear to have the ALSA library installed" >&5 $as_echo "$as_me: error: You do not appear to have the ALSA library installed" >&2;} { (exit 1); exit 1; }; } fi if test "$alsa" = "detect"; then alsa=$lib fi fi { $as_echo "$as_me:$LINENO: checking for JACK support" >&5 $as_echo_n "checking for JACK support... " >&6; } # Check whether --with-jack was given. if test "${with_jack+set}" = set; then withval=$with_jack; jack="$withval" else jack="detect" fi if test "$jack" = "no"; then { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } else { $as_echo "$as_me:$LINENO: checking for jack_client_new in -ljack" >&5 $as_echo_n "checking for jack_client_new in -ljack... " >&6; } if test "${ac_cv_lib_jack_jack_client_new+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ljack $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 jack_client_new (); int main () { return jack_client_new (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_jack_jack_client_new=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_jack_jack_client_new=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_jack_jack_client_new" >&5 $as_echo "$ac_cv_lib_jack_jack_client_new" >&6; } if test "x$ac_cv_lib_jack_jack_client_new" = x""yes; then lib=yes else lib=no fi if test "$lib" = "yes"; then jack_CFLAGS=`pkg-config --cflags jack` jack_LIBS=`pkg-config --libs jack` cat >>confdefs.h <<\_ACEOF #define HAVE_JACK 1 _ACEOF fi if test "$lib" = "no" -a "$jack" = "yes"; then { { $as_echo "$as_me:$LINENO: error: You do not appear to have the JACK library installed. Grab it from http://jackaudio.org" >&5 $as_echo "$as_me: error: You do not appear to have the JACK library installed. Grab it from http://jackaudio.org" >&2;} { (exit 1); exit 1; }; } fi if test "$jack" = "detect"; then jack=$lib fi fi { $as_echo "$as_me:$LINENO: checking for PulseAudio support" >&5 $as_echo_n "checking for PulseAudio support... " >&6; } # Check whether --with-pulse was given. if test "${with_pulse+set}" = set; then withval=$with_pulse; pulse="$withval" else pulse="detect" fi if test "$pulse" = "no"; then { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } else { $as_echo "$as_me:$LINENO: checking for pa_simple_new in -lpulse-simple" >&5 $as_echo_n "checking for pa_simple_new in -lpulse-simple... " >&6; } if test "${ac_cv_lib_pulse_simple_pa_simple_new+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpulse-simple $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 pa_simple_new (); int main () { return pa_simple_new (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_pulse_simple_pa_simple_new=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_pulse_simple_pa_simple_new=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_pulse_simple_pa_simple_new" >&5 $as_echo "$ac_cv_lib_pulse_simple_pa_simple_new" >&6; } if test "x$ac_cv_lib_pulse_simple_pa_simple_new" = x""yes; then lib=yes else lib=no fi if test "$lib" = "yes"; then pulse_CFLAGS=`pkg-config --cflags libpulse-simple` pulse_LIBS=`pkg-config --libs libpulse-simple` cat >>confdefs.h <<\_ACEOF #define HAVE_PULSE 1 _ACEOF fi if test "$lib" = "no" -a "$pulse" = "yes"; then { { $as_echo "$as_me:$LINENO: error: You do not appear to have the PulseAudio installed. Grab it from http://pulseaudio.org/" >&5 $as_echo "$as_me: error: You do not appear to have the PulseAudio installed. Grab it from http://pulseaudio.org/" >&2;} { (exit 1); exit 1; }; } fi if test "$pulse" = "detect"; then pulse=$lib fi fi { $as_echo "$as_me:$LINENO: checking for Sample Rate Converter support" >&5 $as_echo_n "checking for Sample Rate Converter support... " >&6; } # Check whether --with-src was given. if test "${with_src+set}" = set; then withval=$with_src; src="$withval" else src="detect" fi if test "$src" = "no"; then { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } else { $as_echo "$as_me:$LINENO: checking for src_new in -lsamplerate" >&5 $as_echo_n "checking for src_new in -lsamplerate... " >&6; } if test "${ac_cv_lib_samplerate_src_new+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsamplerate $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 src_new (); int main () { return src_new (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_samplerate_src_new=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_samplerate_src_new=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_samplerate_src_new" >&5 $as_echo "$ac_cv_lib_samplerate_src_new" >&6; } if test "x$ac_cv_lib_samplerate_src_new" = x""yes; then lib=yes else lib=no fi if test "$lib" = "yes"; then src_LIBS=`pkg-config --libs samplerate` cat >>confdefs.h <<\_ACEOF #define HAVE_SRC 1 _ACEOF fi if test "$lib" = "no" -a "$src" = "yes"; then { { $as_echo "$as_me:$LINENO: error: You do not appear to have libsamplerate (aka. Secret Rabbit Code) installed. Grab it from http://www.mega-nerd.com/SRC/ " >&5 $as_echo "$as_me: error: You do not appear to have libsamplerate (aka. Secret Rabbit Code) installed. Grab it from http://www.mega-nerd.com/SRC/ " >&2;} { (exit 1); exit 1; }; } fi if test "$src" = "detect"; then src=$lib fi fi { $as_echo "$as_me:$LINENO: checking for sndfile support" >&5 $as_echo_n "checking for sndfile support... " >&6; } # Check whether --with-sndfile was given. if test "${with_sndfile+set}" = set; then withval=$with_sndfile; sndfile="$withval" else sndfile="detect" fi if test "$sndfile" = "no"; then { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } else { $as_echo "$as_me:$LINENO: checking for sf_open in -lsndfile" >&5 $as_echo_n "checking for sf_open in -lsndfile... " >&6; } if test "${ac_cv_lib_sndfile_sf_open+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsndfile $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 sf_open (); int main () { return sf_open (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_sndfile_sf_open=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_sndfile_sf_open=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_sndfile_sf_open" >&5 $as_echo "$ac_cv_lib_sndfile_sf_open" >&6; } if test "x$ac_cv_lib_sndfile_sf_open" = x""yes; then lib=yes else lib=no fi if test "$lib" = "yes"; then sndfile_LIBS=`pkg-config --libs sndfile` cat >>confdefs.h <<\_ACEOF #define HAVE_SNDFILE 1 _ACEOF { $as_echo "$as_me:$LINENO: checking whether sndfile version >= 1.0.12" >&5 $as_echo_n "checking whether sndfile version >= 1.0.12... " >&6; } if pkg-config --exists 'sndfile >= 1.0.12'; then { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } cat >>confdefs.h <<\_ACEOF #define HAVE_SNDFILE_1_0_12 1 _ACEOF else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi { $as_echo "$as_me:$LINENO: checking whether sndfile version >= 1.0.18" >&5 $as_echo_n "checking whether sndfile version >= 1.0.18... " >&6; } if pkg-config --exists 'sndfile >= 1.0.18'; then { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } cat >>confdefs.h <<\_ACEOF #define HAVE_SNDFILE_1_0_18 1 _ACEOF else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi fi if test "$lib" = "no" -a "$sndfile" = "yes"; then { { $as_echo "$as_me:$LINENO: error: You do not appear to have the sndfile library installed. Grab it from http://www.mega-nerd.com/libsndfile/ " >&5 $as_echo "$as_me: error: You do not appear to have the sndfile library installed. Grab it from http://www.mega-nerd.com/libsndfile/ " >&2;} { (exit 1); exit 1; }; } fi if test "$sndfile" = "detect"; then sndfile=$lib fi fi { $as_echo "$as_me:$LINENO: checking for FLAC support" >&5 $as_echo_n "checking for FLAC support... " >&6; } # Check whether --with-flac was given. if test "${with_flac+set}" = set; then withval=$with_flac; flac="$withval" else flac="detect" fi if test "$flac" = "no"; then { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } else { $as_echo "$as_me:$LINENO: checking for FLAC__stream_decoder_init_file in -lFLAC" >&5 $as_echo_n "checking for FLAC__stream_decoder_init_file in -lFLAC... " >&6; } if test "${ac_cv_lib_FLAC_FLAC__stream_decoder_init_file+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lFLAC -logg $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 FLAC__stream_decoder_init_file (); int main () { return FLAC__stream_decoder_init_file (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_FLAC_FLAC__stream_decoder_init_file=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_FLAC_FLAC__stream_decoder_init_file=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_FLAC_FLAC__stream_decoder_init_file" >&5 $as_echo "$ac_cv_lib_FLAC_FLAC__stream_decoder_init_file" >&6; } if test "x$ac_cv_lib_FLAC_FLAC__stream_decoder_init_file" = x""yes; then lib=yes else lib=no fi if test "$lib" = "yes"; then flac_LIBS="-lFLAC" cat >>confdefs.h <<\_ACEOF #define HAVE_FLAC_8 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define HAVE_FLAC 1 _ACEOF fi { $as_echo "$as_me:$LINENO: checking for FLAC__file_decoder_new in -lFLAC" >&5 $as_echo_n "checking for FLAC__file_decoder_new in -lFLAC... " >&6; } if test "${ac_cv_lib_FLAC_FLAC__file_decoder_new+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lFLAC $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 FLAC__file_decoder_new (); int main () { return FLAC__file_decoder_new (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_FLAC_FLAC__file_decoder_new=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_FLAC_FLAC__file_decoder_new=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_FLAC_FLAC__file_decoder_new" >&5 $as_echo "$ac_cv_lib_FLAC_FLAC__file_decoder_new" >&6; } if test "x$ac_cv_lib_FLAC_FLAC__file_decoder_new" = x""yes; then lib2=yes else lib2=no fi if test "$lib2" = "yes"; then flac_LIBS="-lFLAC" cat >>confdefs.h <<\_ACEOF #define HAVE_FLAC_7 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define HAVE_FLAC 1 _ACEOF fi if test "$lib" = "no" -a "$lib2" = "no" -a "$flac" = "yes"; then { { $as_echo "$as_me:$LINENO: error: You do not appear to have the FLAC library installed. Grab it from http://flac.sourceforge.net" >&5 $as_echo "$as_me: error: You do not appear to have the FLAC library installed. Grab it from http://flac.sourceforge.net" >&2;} { (exit 1); exit 1; }; } fi if test "$flac" = "detect"; then if test "$lib2" = "yes" -o "$lib" = "yes"; then flac="yes" else flac="no" { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi fi fi { $as_echo "$as_me:$LINENO: checking for Ogg Vorbis support" >&5 $as_echo_n "checking for Ogg Vorbis support... " >&6; } # Check whether --with-ogg was given. if test "${with_ogg+set}" = set; then withval=$with_ogg; ogg="$withval" else ogg="detect" fi if test "$ogg" = "no"; then { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } else { $as_echo "$as_me:$LINENO: checking for ov_open in -lvorbis" >&5 $as_echo_n "checking for ov_open in -lvorbis... " >&6; } if test "${ac_cv_lib_vorbis_ov_open+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lvorbis -lvorbisfile -logg $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 ov_open (); int main () { return ov_open (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_vorbis_ov_open=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_vorbis_ov_open=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_vorbis_ov_open" >&5 $as_echo "$ac_cv_lib_vorbis_ov_open" >&6; } if test "x$ac_cv_lib_vorbis_ov_open" = x""yes; then lib=yes else lib=no fi if test "$lib" = "yes"; then ogg_LIBS="-logg -lvorbis -lvorbisfile" cat >>confdefs.h <<\_ACEOF #define HAVE_OGG_VORBIS 1 _ACEOF fi if test "$lib" = "no" -a "$ogg" = "yes"; then { { $as_echo "$as_me:$LINENO: error: You do not appear to have the ogg" >&5 $as_echo "$as_me: error: You do not appear to have the ogg" >&2;} { (exit vorbis and vorbisfile libraries installed. Grab them from http://www.xiph.org/ogg/vorbis); exit vorbis and vorbisfile libraries installed. Grab them from http://www.xiph.org/ogg/vorbis; }; } fi if test "$ogg" = "detect"; then ogg=$lib fi fi { $as_echo "$as_me:$LINENO: checking for Ogg Vorbis encoding support" >&5 $as_echo_n "checking for Ogg Vorbis encoding support... " >&6; } # Check whether --with-vorbisenc was given. if test "${with_vorbisenc+set}" = set; then withval=$with_vorbisenc; vorbisenc="$withval" else vorbisenc="detect" fi if test "$vorbisenc" = "no"; then { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } else { $as_echo "$as_me:$LINENO: checking for vorbis_encode_setup_init in -lvorbisenc" >&5 $as_echo_n "checking for vorbis_encode_setup_init in -lvorbisenc... " >&6; } if test "${ac_cv_lib_vorbisenc_vorbis_encode_setup_init+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lvorbisenc -lvorbis -logg $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 vorbis_encode_setup_init (); int main () { return vorbis_encode_setup_init (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_vorbisenc_vorbis_encode_setup_init=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_vorbisenc_vorbis_encode_setup_init=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_vorbisenc_vorbis_encode_setup_init" >&5 $as_echo "$ac_cv_lib_vorbisenc_vorbis_encode_setup_init" >&6; } if test "x$ac_cv_lib_vorbisenc_vorbis_encode_setup_init" = x""yes; then lib=yes else lib=no fi if test "$lib" = "yes"; then vorbisenc_LIBS="-logg -lvorbis -lvorbisenc" cat >>confdefs.h <<\_ACEOF #define HAVE_VORBISENC 1 _ACEOF fi if test "$lib" = "no" -a "$vorbisenc" = "yes"; then { { $as_echo "$as_me:$LINENO: error: You do not appear to have the ogg" >&5 $as_echo "$as_me: error: You do not appear to have the ogg" >&2;} { (exit vorbis and vorbisenc libraries installed. Grab them from http://www.xiph.org/ogg/vorbis); exit vorbis and vorbisenc libraries installed. Grab them from http://www.xiph.org/ogg/vorbis; }; } fi if test "$vorbisenc" = "detect"; then vorbisenc=$lib fi fi { $as_echo "$as_me:$LINENO: checking for Ogg Speex support" >&5 $as_echo_n "checking for Ogg Speex support... " >&6; } # Check whether --with-speex was given. if test "${with_speex+set}" = set; then withval=$with_speex; speex="$withval" else speex="detect" fi if test "$speex" = "no"; then { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } else { $as_echo "$as_me:$LINENO: checking for oggz_open in -loggz" >&5 $as_echo_n "checking for oggz_open in -loggz... " >&6; } if test "${ac_cv_lib_oggz_oggz_open+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-loggz -loggz -logg $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 oggz_open (); int main () { return oggz_open (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_oggz_oggz_open=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_oggz_oggz_open=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_oggz_oggz_open" >&5 $as_echo "$ac_cv_lib_oggz_oggz_open" >&6; } if test "x$ac_cv_lib_oggz_oggz_open" = x""yes; then oggzlib=yes else oggzlib=no fi { $as_echo "$as_me:$LINENO: checking for speex_bits_init in -lspeex" >&5 $as_echo_n "checking for speex_bits_init in -lspeex... " >&6; } if test "${ac_cv_lib_speex_speex_bits_init+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lspeex -lspeex $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 speex_bits_init (); int main () { return speex_bits_init (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_speex_speex_bits_init=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_speex_speex_bits_init=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_speex_speex_bits_init" >&5 $as_echo "$ac_cv_lib_speex_speex_bits_init" >&6; } if test "x$ac_cv_lib_speex_speex_bits_init" = x""yes; then speexlib=yes else speexlib=no fi if test "$oggzlib" = "yes"; then if test "$speexlib" = "yes"; then speex_LIBS="-loggz -logg -lspeex" lib="yes" cat >>confdefs.h <<\_ACEOF #define HAVE_SPEEX 1 _ACEOF else lib="no" fi else lib="no" fi if test "$lib" = "no" -a "$speex" = "yes"; then { { $as_echo "$as_me:$LINENO: error: You do not appear to have the oggz and speex libraries installed. Grab them from http://www.annodex.net/software/liboggz and http://speex.org" >&5 $as_echo "$as_me: error: You do not appear to have the oggz and speex libraries installed. Grab them from http://www.annodex.net/software/liboggz and http://speex.org" >&2;} { (exit 1); exit 1; }; } fi if test "$speex" = "detect"; then speex=$lib fi fi { $as_echo "$as_me:$LINENO: checking for MPEG audio support" >&5 $as_echo_n "checking for MPEG audio support... " >&6; } # Check whether --with-mpeg was given. if test "${with_mpeg+set}" = set; then withval=$with_mpeg; mpeg="$withval" else mpeg="detect" fi if test "$mpeg" = "no"; then { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } else if test "${ac_cv_header_mad_h+set}" = set; then { $as_echo "$as_me:$LINENO: checking for mad.h" >&5 $as_echo_n "checking for mad.h... " >&6; } if test "${ac_cv_header_mad_h+set}" = set; then $as_echo_n "(cached) " >&6 fi { $as_echo "$as_me:$LINENO: result: $ac_cv_header_mad_h" >&5 $as_echo "$ac_cv_header_mad_h" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking mad.h usability" >&5 $as_echo_n "checking mad.h usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking mad.h presence" >&5 $as_echo_n "checking mad.h presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { $as_echo "$as_me:$LINENO: WARNING: mad.h: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: mad.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: mad.h: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: mad.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: mad.h: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: mad.h: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: mad.h: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: mad.h: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: mad.h: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: mad.h: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: mad.h: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: mad.h: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: mad.h: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: mad.h: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: mad.h: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: mad.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## -------------------------------------------------- ## ## Report this to http://aqualung.factorial.hu/mantis ## ## -------------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for mad.h" >&5 $as_echo_n "checking for mad.h... " >&6; } if test "${ac_cv_header_mad_h+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_header_mad_h=$ac_header_preproc fi { $as_echo "$as_me:$LINENO: result: $ac_cv_header_mad_h" >&5 $as_echo "$ac_cv_header_mad_h" >&6; } fi if test "x$ac_cv_header_mad_h" = x""yes; then hdr=yes else hdr=no fi if test "$hdr" = "no"; then lib="no" else { $as_echo "$as_me:$LINENO: checking for mad_decoder_init in -lmad" >&5 $as_echo_n "checking for mad_decoder_init in -lmad... " >&6; } if test "${ac_cv_lib_mad_mad_decoder_init+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lmad $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 mad_decoder_init (); int main () { return mad_decoder_init (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_mad_mad_decoder_init=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_mad_mad_decoder_init=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_mad_mad_decoder_init" >&5 $as_echo "$ac_cv_lib_mad_mad_decoder_init" >&6; } if test "x$ac_cv_lib_mad_mad_decoder_init" = x""yes; then lib=yes else lib=no fi if test "$lib" = "yes"; then mad_LIBS="-lmad" cat >>confdefs.h <<\_ACEOF #define HAVE_MPEG 1 _ACEOF fi fi if test "$lib" = "no" -a "$mpeg" = "yes"; then { { $as_echo "$as_me:$LINENO: error: You do not appear to have the MAD library installed. Grab it from http://www.underbit.com/products/mad/" >&5 $as_echo "$as_me: error: You do not appear to have the MAD library installed. Grab it from http://www.underbit.com/products/mad/" >&2;} { (exit 1); exit 1; }; } fi if test "$mpeg" = "detect"; then mpeg=$lib fi fi { $as_echo "$as_me:$LINENO: checking for MOD audio support" >&5 $as_echo_n "checking for MOD audio support... " >&6; } # Check whether --with-mod was given. if test "${with_mod+set}" = set; then withval=$with_mod; mod="$withval" else mod="detect" fi if test "$mod" = "no"; then { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } else { $as_echo "$as_me:$LINENO: checking for ModPlug_Load in -lmodplug" >&5 $as_echo_n "checking for ModPlug_Load in -lmodplug... " >&6; } if test "${ac_cv_lib_modplug_ModPlug_Load+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lmodplug -lstdc++ -lm $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 ModPlug_Load (); int main () { return ModPlug_Load (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_modplug_ModPlug_Load=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_modplug_ModPlug_Load=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_modplug_ModPlug_Load" >&5 $as_echo "$ac_cv_lib_modplug_ModPlug_Load" >&6; } if test "x$ac_cv_lib_modplug_ModPlug_Load" = x""yes; then lib=yes else lib=no fi if test "$lib" = "yes"; then mod_LIBS=`pkg-config --libs libmodplug` cat >>confdefs.h <<\_ACEOF #define HAVE_MOD 1 _ACEOF fi if test "$lib" = "no" -a "$mod" = "yes"; then { { $as_echo "$as_me:$LINENO: error: You do not appear to have the libmodplug library installed. Grab it from http://modplug-xmms.sourceforge.net/" >&5 $as_echo "$as_me: error: You do not appear to have the libmodplug library installed. Grab it from http://modplug-xmms.sourceforge.net/" >&2;} { (exit 1); exit 1; }; } fi if test "$mod" = "detect"; then mod=$lib fi if test "$mod" = "yes"; then { $as_echo "$as_me:$LINENO: checking for Module info" >&5 $as_echo_n "checking for Module info... " >&6; } { $as_echo "$as_me:$LINENO: checking whether libmodplug version >= 0.8" >&5 $as_echo_n "checking whether libmodplug version >= 0.8... " >&6; } if pkg-config --exists 'libmodplug >= 0.8'; then { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } cat >>confdefs.h <<\_ACEOF #define HAVE_MOD_INFO 1 _ACEOF else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi fi fi { $as_echo "$as_me:$LINENO: checking for Musepack support" >&5 $as_echo_n "checking for Musepack support... " >&6; } # Check whether --with-mpc was given. if test "${with_mpc+set}" = set; then withval=$with_mpc; mpc="$withval" else mpc="detect" fi if test "$mpc" = "no"; then { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } else { $as_echo "$as_me:$LINENO: checking for mpc_demux_init in -lmpcdec" >&5 $as_echo_n "checking for mpc_demux_init in -lmpcdec... " >&6; } if test "${ac_cv_lib_mpcdec_mpc_demux_init+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lmpcdec -lstdc++ $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 mpc_demux_init (); int main () { return mpc_demux_init (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_mpcdec_mpc_demux_init=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_mpcdec_mpc_demux_init=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_mpcdec_mpc_demux_init" >&5 $as_echo "$ac_cv_lib_mpcdec_mpc_demux_init" >&6; } if test "x$ac_cv_lib_mpcdec_mpc_demux_init" = x""yes; then lib=yes else { $as_echo "$as_me:$LINENO: checking for mpc_streaminfo_init in -lmpcdec" >&5 $as_echo_n "checking for mpc_streaminfo_init in -lmpcdec... " >&6; } if test "${ac_cv_lib_mpcdec_mpc_streaminfo_init+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lmpcdec -lstdc++ $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 mpc_streaminfo_init (); int main () { return mpc_streaminfo_init (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_mpcdec_mpc_streaminfo_init=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_mpcdec_mpc_streaminfo_init=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_mpcdec_mpc_streaminfo_init" >&5 $as_echo "$ac_cv_lib_mpcdec_mpc_streaminfo_init" >&6; } if test "x$ac_cv_lib_mpcdec_mpc_streaminfo_init" = x""yes; then lib=yes cat >>confdefs.h <<\_ACEOF #define MPC_OLD_API 1 _ACEOF fi fi if test "$lib" = "yes"; then mpc_LIBS="-lmpcdec -lstdc++" cat >>confdefs.h <<\_ACEOF #define HAVE_MPC 1 _ACEOF fi if test "$lib" != "yes" -a "$mpc" = "yes"; then { { $as_echo "$as_me:$LINENO: error: You do not appear to have the Musepack decoder library (libmpcdec) installed. Grab it from http://www.musepack.net" >&5 $as_echo "$as_me: error: You do not appear to have the Musepack decoder library (libmpcdec) installed. Grab it from http://www.musepack.net" >&2;} { (exit 1); exit 1; }; } fi if test "$mpc" = "detect"; then mpc=$lib fi fi { $as_echo "$as_me:$LINENO: checking for Monkey's Audio Codec support" >&5 $as_echo_n "checking for Monkey's Audio Codec support... " >&6; } # Check whether --with-mac was given. if test "${with_mac+set}" = set; then withval=$with_mac; mac="$withval" else mac="detect" fi if test "$mac" = "no"; then { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } mac_LIBS="-lstdc++" else { $as_echo "$as_me:$LINENO: checking for CreateIAPEDecompress in -lmac" >&5 $as_echo_n "checking for CreateIAPEDecompress in -lmac... " >&6; } if test "${ac_cv_lib_mac_CreateIAPEDecompress+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lmac -lstdc++ $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 CreateIAPEDecompress (); int main () { return CreateIAPEDecompress (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_mac_CreateIAPEDecompress=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_mac_CreateIAPEDecompress=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_mac_CreateIAPEDecompress" >&5 $as_echo "$ac_cv_lib_mac_CreateIAPEDecompress" >&6; } if test "x$ac_cv_lib_mac_CreateIAPEDecompress" = x""yes; then lib=yes else lib=no fi if test "$lib" = "yes"; then mac_LIBS="-lmac -lstdc++" cat >>confdefs.h <<\_ACEOF #define HAVE_MAC 1 _ACEOF else mac_LIBS="-lstdc++" fi if test "$lib" = "no" -a "$mac" = "yes"; then { { $as_echo "$as_me:$LINENO: error: You do not appear to have the Monkey's Audio Codec decoder library installed. Grab it from http://etree.org/shnutils/shntool/support/formats/ape/unix/" >&5 $as_echo "$as_me: error: You do not appear to have the Monkey's Audio Codec decoder library installed. Grab it from http://etree.org/shnutils/shntool/support/formats/ape/unix/" >&2;} { (exit 1); exit 1; }; } fi if test "$mac" = "detect"; then mac=$lib fi fi { $as_echo "$as_me:$LINENO: checking for LAVC support" >&5 $as_echo_n "checking for LAVC support... " >&6; } # Check whether --with-lavc was given. if test "${with_lavc+set}" = set; then withval=$with_lavc; lavc="$withval" else lavc="detect" fi if test "$lavc" = "no"; then { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } else if test "${ac_cv_header_avcodec_h+set}" = set; then { $as_echo "$as_me:$LINENO: checking for avcodec.h" >&5 $as_echo_n "checking for avcodec.h... " >&6; } if test "${ac_cv_header_avcodec_h+set}" = set; then $as_echo_n "(cached) " >&6 fi { $as_echo "$as_me:$LINENO: result: $ac_cv_header_avcodec_h" >&5 $as_echo "$ac_cv_header_avcodec_h" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking avcodec.h usability" >&5 $as_echo_n "checking avcodec.h usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking avcodec.h presence" >&5 $as_echo_n "checking avcodec.h presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { $as_echo "$as_me:$LINENO: WARNING: avcodec.h: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: avcodec.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: avcodec.h: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: avcodec.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: avcodec.h: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: avcodec.h: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: avcodec.h: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: avcodec.h: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: avcodec.h: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: avcodec.h: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: avcodec.h: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: avcodec.h: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: avcodec.h: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: avcodec.h: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: avcodec.h: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: avcodec.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## -------------------------------------------------- ## ## Report this to http://aqualung.factorial.hu/mantis ## ## -------------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for avcodec.h" >&5 $as_echo_n "checking for avcodec.h... " >&6; } if test "${ac_cv_header_avcodec_h+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_header_avcodec_h=$ac_header_preproc fi { $as_echo "$as_me:$LINENO: result: $ac_cv_header_avcodec_h" >&5 $as_echo "$ac_cv_header_avcodec_h" >&6; } fi if test "x$ac_cv_header_avcodec_h" = x""yes; then avc_hdr=yes else avc_hdr=no fi if test "$avc_hdr" = "yes"; then cat >>confdefs.h <<\_ACEOF #define HAVE_AVCODEC_H 1 _ACEOF else if test "${ac_cv_header_ffmpeg_avcodec_h+set}" = set; then { $as_echo "$as_me:$LINENO: checking for ffmpeg/avcodec.h" >&5 $as_echo_n "checking for ffmpeg/avcodec.h... " >&6; } if test "${ac_cv_header_ffmpeg_avcodec_h+set}" = set; then $as_echo_n "(cached) " >&6 fi { $as_echo "$as_me:$LINENO: result: $ac_cv_header_ffmpeg_avcodec_h" >&5 $as_echo "$ac_cv_header_ffmpeg_avcodec_h" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking ffmpeg/avcodec.h usability" >&5 $as_echo_n "checking ffmpeg/avcodec.h usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking ffmpeg/avcodec.h presence" >&5 $as_echo_n "checking ffmpeg/avcodec.h presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { $as_echo "$as_me:$LINENO: WARNING: ffmpeg/avcodec.h: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: ffmpeg/avcodec.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: ffmpeg/avcodec.h: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: ffmpeg/avcodec.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: ffmpeg/avcodec.h: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: ffmpeg/avcodec.h: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: ffmpeg/avcodec.h: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: ffmpeg/avcodec.h: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: ffmpeg/avcodec.h: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: ffmpeg/avcodec.h: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: ffmpeg/avcodec.h: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: ffmpeg/avcodec.h: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: ffmpeg/avcodec.h: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: ffmpeg/avcodec.h: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: ffmpeg/avcodec.h: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: ffmpeg/avcodec.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## -------------------------------------------------- ## ## Report this to http://aqualung.factorial.hu/mantis ## ## -------------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for ffmpeg/avcodec.h" >&5 $as_echo_n "checking for ffmpeg/avcodec.h... " >&6; } if test "${ac_cv_header_ffmpeg_avcodec_h+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_header_ffmpeg_avcodec_h=$ac_header_preproc fi { $as_echo "$as_me:$LINENO: result: $ac_cv_header_ffmpeg_avcodec_h" >&5 $as_echo "$ac_cv_header_ffmpeg_avcodec_h" >&6; } fi if test "x$ac_cv_header_ffmpeg_avcodec_h" = x""yes; then avc_hdr=yes else avc_hdr=no fi if test "$avc_hdr" = "yes"; then cat >>confdefs.h <<\_ACEOF #define HAVE_FFMPEG_AVCODEC_H 1 _ACEOF else if test "${ac_cv_header_libavcodec_avcodec_h+set}" = set; then { $as_echo "$as_me:$LINENO: checking for libavcodec/avcodec.h" >&5 $as_echo_n "checking for libavcodec/avcodec.h... " >&6; } if test "${ac_cv_header_libavcodec_avcodec_h+set}" = set; then $as_echo_n "(cached) " >&6 fi { $as_echo "$as_me:$LINENO: result: $ac_cv_header_libavcodec_avcodec_h" >&5 $as_echo "$ac_cv_header_libavcodec_avcodec_h" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking libavcodec/avcodec.h usability" >&5 $as_echo_n "checking libavcodec/avcodec.h usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking libavcodec/avcodec.h presence" >&5 $as_echo_n "checking libavcodec/avcodec.h presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { $as_echo "$as_me:$LINENO: WARNING: libavcodec/avcodec.h: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: libavcodec/avcodec.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: libavcodec/avcodec.h: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: libavcodec/avcodec.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: libavcodec/avcodec.h: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: libavcodec/avcodec.h: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: libavcodec/avcodec.h: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: libavcodec/avcodec.h: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: libavcodec/avcodec.h: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: libavcodec/avcodec.h: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: libavcodec/avcodec.h: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: libavcodec/avcodec.h: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: libavcodec/avcodec.h: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: libavcodec/avcodec.h: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: libavcodec/avcodec.h: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: libavcodec/avcodec.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## -------------------------------------------------- ## ## Report this to http://aqualung.factorial.hu/mantis ## ## -------------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for libavcodec/avcodec.h" >&5 $as_echo_n "checking for libavcodec/avcodec.h... " >&6; } if test "${ac_cv_header_libavcodec_avcodec_h+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_header_libavcodec_avcodec_h=$ac_header_preproc fi { $as_echo "$as_me:$LINENO: result: $ac_cv_header_libavcodec_avcodec_h" >&5 $as_echo "$ac_cv_header_libavcodec_avcodec_h" >&6; } fi if test "x$ac_cv_header_libavcodec_avcodec_h" = x""yes; then avc_hdr=yes else avc_hdr=no fi if test "$avc_hdr" = "yes"; then cat >>confdefs.h <<\_ACEOF #define HAVE_LIBAVCODEC_AVCODEC_H 1 _ACEOF else if test "${ac_cv_header_ffmpeg_libavcodec_avcodec_h+set}" = set; then { $as_echo "$as_me:$LINENO: checking for ffmpeg/libavcodec/avcodec.h" >&5 $as_echo_n "checking for ffmpeg/libavcodec/avcodec.h... " >&6; } if test "${ac_cv_header_ffmpeg_libavcodec_avcodec_h+set}" = set; then $as_echo_n "(cached) " >&6 fi { $as_echo "$as_me:$LINENO: result: $ac_cv_header_ffmpeg_libavcodec_avcodec_h" >&5 $as_echo "$ac_cv_header_ffmpeg_libavcodec_avcodec_h" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking ffmpeg/libavcodec/avcodec.h usability" >&5 $as_echo_n "checking ffmpeg/libavcodec/avcodec.h usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking ffmpeg/libavcodec/avcodec.h presence" >&5 $as_echo_n "checking ffmpeg/libavcodec/avcodec.h presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { $as_echo "$as_me:$LINENO: WARNING: ffmpeg/libavcodec/avcodec.h: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: ffmpeg/libavcodec/avcodec.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: ffmpeg/libavcodec/avcodec.h: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: ffmpeg/libavcodec/avcodec.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: ffmpeg/libavcodec/avcodec.h: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: ffmpeg/libavcodec/avcodec.h: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: ffmpeg/libavcodec/avcodec.h: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: ffmpeg/libavcodec/avcodec.h: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: ffmpeg/libavcodec/avcodec.h: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: ffmpeg/libavcodec/avcodec.h: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: ffmpeg/libavcodec/avcodec.h: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: ffmpeg/libavcodec/avcodec.h: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: ffmpeg/libavcodec/avcodec.h: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: ffmpeg/libavcodec/avcodec.h: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: ffmpeg/libavcodec/avcodec.h: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: ffmpeg/libavcodec/avcodec.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## -------------------------------------------------- ## ## Report this to http://aqualung.factorial.hu/mantis ## ## -------------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for ffmpeg/libavcodec/avcodec.h" >&5 $as_echo_n "checking for ffmpeg/libavcodec/avcodec.h... " >&6; } if test "${ac_cv_header_ffmpeg_libavcodec_avcodec_h+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_header_ffmpeg_libavcodec_avcodec_h=$ac_header_preproc fi { $as_echo "$as_me:$LINENO: result: $ac_cv_header_ffmpeg_libavcodec_avcodec_h" >&5 $as_echo "$ac_cv_header_ffmpeg_libavcodec_avcodec_h" >&6; } fi if test "x$ac_cv_header_ffmpeg_libavcodec_avcodec_h" = x""yes; then avc_hdr=yes else avc_hdr=no fi if test "$avc_hdr" = "yes"; then cat >>confdefs.h <<\_ACEOF #define HAVE_FFMPEG_LIBAVCODEC_AVCODEC_H 1 _ACEOF else 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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_path_PKG_CONFIG+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:$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:$LINENO: result: $PKG_CONFIG" >&5 $as_echo "$PKG_CONFIG" >&6; } else { $as_echo "$as_me:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_path_ac_pt_PKG_CONFIG+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$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:$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:$LINENO: result: $ac_pt_PKG_CONFIG" >&5 $as_echo "$ac_pt_PKG_CONFIG" >&6; } else { $as_echo "$as_me:$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:$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:$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:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } PKG_CONFIG="" fi fi pkg_failed=no { $as_echo "$as_me:$LINENO: checking for LIBAVCODEC" >&5 $as_echo_n "checking for LIBAVCODEC... " >&6; } if test -n "$LIBAVCODEC_CFLAGS"; then pkg_cv_LIBAVCODEC_CFLAGS="$LIBAVCODEC_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { ($as_echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"libavcodec\"") >&5 ($PKG_CONFIG --exists --print-errors "libavcodec") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then pkg_cv_LIBAVCODEC_CFLAGS=`$PKG_CONFIG --cflags "libavcodec" 2>/dev/null` else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$LIBAVCODEC_LIBS"; then pkg_cv_LIBAVCODEC_LIBS="$LIBAVCODEC_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { ($as_echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"libavcodec\"") >&5 ($PKG_CONFIG --exists --print-errors "libavcodec") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then pkg_cv_LIBAVCODEC_LIBS=`$PKG_CONFIG --libs "libavcodec" 2>/dev/null` else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then 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 LIBAVCODEC_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "libavcodec" 2>&1` else LIBAVCODEC_PKG_ERRORS=`$PKG_CONFIG --print-errors "libavcodec" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$LIBAVCODEC_PKG_ERRORS" >&5 { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } avc_hdr=no elif test $pkg_failed = untried; then avc_hdr=no else LIBAVCODEC_CFLAGS=$pkg_cv_LIBAVCODEC_CFLAGS LIBAVCODEC_LIBS=$pkg_cv_LIBAVCODEC_LIBS { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } avc_hdr=yes fi if test "$avc_hdr" = "yes"; then cat >>confdefs.h <<\_ACEOF #define HAVE_LIBAVCODEC_AVCODEC_H 1 _ACEOF fi fi fi fi fi if test "${ac_cv_header_avformat_h+set}" = set; then { $as_echo "$as_me:$LINENO: checking for avformat.h" >&5 $as_echo_n "checking for avformat.h... " >&6; } if test "${ac_cv_header_avformat_h+set}" = set; then $as_echo_n "(cached) " >&6 fi { $as_echo "$as_me:$LINENO: result: $ac_cv_header_avformat_h" >&5 $as_echo "$ac_cv_header_avformat_h" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking avformat.h usability" >&5 $as_echo_n "checking avformat.h usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking avformat.h presence" >&5 $as_echo_n "checking avformat.h presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { $as_echo "$as_me:$LINENO: WARNING: avformat.h: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: avformat.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: avformat.h: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: avformat.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: avformat.h: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: avformat.h: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: avformat.h: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: avformat.h: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: avformat.h: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: avformat.h: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: avformat.h: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: avformat.h: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: avformat.h: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: avformat.h: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: avformat.h: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: avformat.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## -------------------------------------------------- ## ## Report this to http://aqualung.factorial.hu/mantis ## ## -------------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for avformat.h" >&5 $as_echo_n "checking for avformat.h... " >&6; } if test "${ac_cv_header_avformat_h+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_header_avformat_h=$ac_header_preproc fi { $as_echo "$as_me:$LINENO: result: $ac_cv_header_avformat_h" >&5 $as_echo "$ac_cv_header_avformat_h" >&6; } fi if test "x$ac_cv_header_avformat_h" = x""yes; then avf_hdr=yes else avf_hdr=no fi if test "$avf_hdr" = "yes"; then cat >>confdefs.h <<\_ACEOF #define HAVE_AVFORMAT_H 1 _ACEOF else if test "${ac_cv_header_ffmpeg_avformat_h+set}" = set; then { $as_echo "$as_me:$LINENO: checking for ffmpeg/avformat.h" >&5 $as_echo_n "checking for ffmpeg/avformat.h... " >&6; } if test "${ac_cv_header_ffmpeg_avformat_h+set}" = set; then $as_echo_n "(cached) " >&6 fi { $as_echo "$as_me:$LINENO: result: $ac_cv_header_ffmpeg_avformat_h" >&5 $as_echo "$ac_cv_header_ffmpeg_avformat_h" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking ffmpeg/avformat.h usability" >&5 $as_echo_n "checking ffmpeg/avformat.h usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking ffmpeg/avformat.h presence" >&5 $as_echo_n "checking ffmpeg/avformat.h presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { $as_echo "$as_me:$LINENO: WARNING: ffmpeg/avformat.h: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: ffmpeg/avformat.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: ffmpeg/avformat.h: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: ffmpeg/avformat.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: ffmpeg/avformat.h: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: ffmpeg/avformat.h: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: ffmpeg/avformat.h: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: ffmpeg/avformat.h: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: ffmpeg/avformat.h: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: ffmpeg/avformat.h: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: ffmpeg/avformat.h: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: ffmpeg/avformat.h: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: ffmpeg/avformat.h: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: ffmpeg/avformat.h: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: ffmpeg/avformat.h: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: ffmpeg/avformat.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## -------------------------------------------------- ## ## Report this to http://aqualung.factorial.hu/mantis ## ## -------------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for ffmpeg/avformat.h" >&5 $as_echo_n "checking for ffmpeg/avformat.h... " >&6; } if test "${ac_cv_header_ffmpeg_avformat_h+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_header_ffmpeg_avformat_h=$ac_header_preproc fi { $as_echo "$as_me:$LINENO: result: $ac_cv_header_ffmpeg_avformat_h" >&5 $as_echo "$ac_cv_header_ffmpeg_avformat_h" >&6; } fi if test "x$ac_cv_header_ffmpeg_avformat_h" = x""yes; then avf_hdr=yes else avf_hdr=no fi if test "$avf_hdr" = "yes"; then cat >>confdefs.h <<\_ACEOF #define HAVE_FFMPEG_AVFORMAT_H 1 _ACEOF else if test "${ac_cv_header_libavformat_avformat_h+set}" = set; then { $as_echo "$as_me:$LINENO: checking for libavformat/avformat.h" >&5 $as_echo_n "checking for libavformat/avformat.h... " >&6; } if test "${ac_cv_header_libavformat_avformat_h+set}" = set; then $as_echo_n "(cached) " >&6 fi { $as_echo "$as_me:$LINENO: result: $ac_cv_header_libavformat_avformat_h" >&5 $as_echo "$ac_cv_header_libavformat_avformat_h" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking libavformat/avformat.h usability" >&5 $as_echo_n "checking libavformat/avformat.h usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking libavformat/avformat.h presence" >&5 $as_echo_n "checking libavformat/avformat.h presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { $as_echo "$as_me:$LINENO: WARNING: libavformat/avformat.h: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: libavformat/avformat.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: libavformat/avformat.h: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: libavformat/avformat.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: libavformat/avformat.h: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: libavformat/avformat.h: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: libavformat/avformat.h: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: libavformat/avformat.h: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: libavformat/avformat.h: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: libavformat/avformat.h: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: libavformat/avformat.h: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: libavformat/avformat.h: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: libavformat/avformat.h: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: libavformat/avformat.h: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: libavformat/avformat.h: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: libavformat/avformat.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## -------------------------------------------------- ## ## Report this to http://aqualung.factorial.hu/mantis ## ## -------------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for libavformat/avformat.h" >&5 $as_echo_n "checking for libavformat/avformat.h... " >&6; } if test "${ac_cv_header_libavformat_avformat_h+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_header_libavformat_avformat_h=$ac_header_preproc fi { $as_echo "$as_me:$LINENO: result: $ac_cv_header_libavformat_avformat_h" >&5 $as_echo "$ac_cv_header_libavformat_avformat_h" >&6; } fi if test "x$ac_cv_header_libavformat_avformat_h" = x""yes; then avf_hdr=yes else avf_hdr=no fi if test "$avf_hdr" = "yes"; then cat >>confdefs.h <<\_ACEOF #define HAVE_LIBAVFORMAT_AVFORMAT_H 1 _ACEOF else if test "${ac_cv_header_ffmpeg_libavformat_avformat_h+set}" = set; then { $as_echo "$as_me:$LINENO: checking for ffmpeg/libavformat/avformat.h" >&5 $as_echo_n "checking for ffmpeg/libavformat/avformat.h... " >&6; } if test "${ac_cv_header_ffmpeg_libavformat_avformat_h+set}" = set; then $as_echo_n "(cached) " >&6 fi { $as_echo "$as_me:$LINENO: result: $ac_cv_header_ffmpeg_libavformat_avformat_h" >&5 $as_echo "$ac_cv_header_ffmpeg_libavformat_avformat_h" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking ffmpeg/libavformat/avformat.h usability" >&5 $as_echo_n "checking ffmpeg/libavformat/avformat.h usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking ffmpeg/libavformat/avformat.h presence" >&5 $as_echo_n "checking ffmpeg/libavformat/avformat.h presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { $as_echo "$as_me:$LINENO: WARNING: ffmpeg/libavformat/avformat.h: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: ffmpeg/libavformat/avformat.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: ffmpeg/libavformat/avformat.h: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: ffmpeg/libavformat/avformat.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: ffmpeg/libavformat/avformat.h: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: ffmpeg/libavformat/avformat.h: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: ffmpeg/libavformat/avformat.h: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: ffmpeg/libavformat/avformat.h: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: ffmpeg/libavformat/avformat.h: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: ffmpeg/libavformat/avformat.h: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: ffmpeg/libavformat/avformat.h: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: ffmpeg/libavformat/avformat.h: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: ffmpeg/libavformat/avformat.h: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: ffmpeg/libavformat/avformat.h: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: ffmpeg/libavformat/avformat.h: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: ffmpeg/libavformat/avformat.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## -------------------------------------------------- ## ## Report this to http://aqualung.factorial.hu/mantis ## ## -------------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for ffmpeg/libavformat/avformat.h" >&5 $as_echo_n "checking for ffmpeg/libavformat/avformat.h... " >&6; } if test "${ac_cv_header_ffmpeg_libavformat_avformat_h+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_header_ffmpeg_libavformat_avformat_h=$ac_header_preproc fi { $as_echo "$as_me:$LINENO: result: $ac_cv_header_ffmpeg_libavformat_avformat_h" >&5 $as_echo "$ac_cv_header_ffmpeg_libavformat_avformat_h" >&6; } fi if test "x$ac_cv_header_ffmpeg_libavformat_avformat_h" = x""yes; then avf_hdr=yes else avf_hdr=no fi if test "$avf_hdr" = "yes"; then cat >>confdefs.h <<\_ACEOF #define HAVE_FFMPEG_LIBAVFORMAT_AVFORMAT_H 1 _ACEOF else pkg_failed=no { $as_echo "$as_me:$LINENO: checking for LIBAVFORMAT" >&5 $as_echo_n "checking for LIBAVFORMAT... " >&6; } if test -n "$LIBAVFORMAT_CFLAGS"; then pkg_cv_LIBAVFORMAT_CFLAGS="$LIBAVFORMAT_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { ($as_echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"libavformat\"") >&5 ($PKG_CONFIG --exists --print-errors "libavformat") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then pkg_cv_LIBAVFORMAT_CFLAGS=`$PKG_CONFIG --cflags "libavformat" 2>/dev/null` else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$LIBAVFORMAT_LIBS"; then pkg_cv_LIBAVFORMAT_LIBS="$LIBAVFORMAT_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { ($as_echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"libavformat\"") >&5 ($PKG_CONFIG --exists --print-errors "libavformat") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then pkg_cv_LIBAVFORMAT_LIBS=`$PKG_CONFIG --libs "libavformat" 2>/dev/null` else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then 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 LIBAVFORMAT_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "libavformat" 2>&1` else LIBAVFORMAT_PKG_ERRORS=`$PKG_CONFIG --print-errors "libavformat" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$LIBAVFORMAT_PKG_ERRORS" >&5 { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } avf_hdr=no elif test $pkg_failed = untried; then avf_hdr=no else LIBAVFORMAT_CFLAGS=$pkg_cv_LIBAVFORMAT_CFLAGS LIBAVFORMAT_LIBS=$pkg_cv_LIBAVFORMAT_LIBS { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } avf_hdr=yes fi if test "$avf_hdr" = "yes"; then cat >>confdefs.h <<\_ACEOF #define HAVE_LIBAVFORMAT_AVFORMAT_H 1 _ACEOF fi fi fi fi fi { $as_echo "$as_me:$LINENO: checking for av_open_input_file in -lavformat" >&5 $as_echo_n "checking for av_open_input_file in -lavformat... " >&6; } if test "${ac_cv_lib_avformat_av_open_input_file+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lavformat -lavcodec -lavutil -lz $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 av_open_input_file (); int main () { return av_open_input_file (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_avformat_av_open_input_file=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_avformat_av_open_input_file=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_avformat_av_open_input_file" >&5 $as_echo "$ac_cv_lib_avformat_av_open_input_file" >&6; } if test "x$ac_cv_lib_avformat_av_open_input_file" = x""yes; then avf_lib=yes else avf_lib=no fi { $as_echo "$as_me:$LINENO: checking for avcodec_open in -lavcodec" >&5 $as_echo_n "checking for avcodec_open in -lavcodec... " >&6; } if test "${ac_cv_lib_avcodec_avcodec_open+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lavcodec -lavformat -lavutil -lz $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 avcodec_open (); int main () { return avcodec_open (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_avcodec_avcodec_open=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_avcodec_avcodec_open=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_avcodec_avcodec_open" >&5 $as_echo "$ac_cv_lib_avcodec_avcodec_open" >&6; } if test "x$ac_cv_lib_avcodec_avcodec_open" = x""yes; then avc_lib=yes else avc_lib=no fi if test "$avc_hdr" = "yes" -a "$avf_hdr" = "yes" -a "$avc_lib" = "yes" -a "$avf_lib" = "yes" ; then lavc_LIBS="-lavformat -lavcodec -lavutil -lz" cat >>confdefs.h <<\_ACEOF #define HAVE_LAVC 1 _ACEOF lavc="yes" else if test "$lavc" = "yes"; then { { $as_echo "$as_me:$LINENO: error: You do not appear to have the LAVC decoder library (FFmpeg) installed. Grab it from http://ffmpeg.mplayerhq.hu/" >&5 $as_echo "$as_me: error: You do not appear to have the LAVC decoder library (FFmpeg) installed. Grab it from http://ffmpeg.mplayerhq.hu/" >&2;} { (exit 1); exit 1; }; } fi lavc="no" fi fi { $as_echo "$as_me:$LINENO: checking for LAME (MP3 encoding) support" >&5 $as_echo_n "checking for LAME (MP3 encoding) support... " >&6; } # Check whether --with-lame was given. if test "${with_lame+set}" = set; then withval=$with_lame; lame="$withval" else lame="detect" fi if test "$lame" = "no"; then { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } else { $as_echo "$as_me:$LINENO: checking for lame_init in -lmp3lame" >&5 $as_echo_n "checking for lame_init in -lmp3lame... " >&6; } if test "${ac_cv_lib_mp3lame_lame_init+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lmp3lame $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 lame_init (); int main () { return lame_init (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_mp3lame_lame_init=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_mp3lame_lame_init=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_mp3lame_lame_init" >&5 $as_echo "$ac_cv_lib_mp3lame_lame_init" >&6; } if test "x$ac_cv_lib_mp3lame_lame_init" = x""yes; then lib=yes else lib=no fi if test "$lib" = "yes"; then lame_LIBS="-lmp3lame" cat >>confdefs.h <<\_ACEOF #define HAVE_LAME 1 _ACEOF fi if test "$lib" = "no" -a "$lame" = "yes"; then { { $as_echo "$as_me:$LINENO: error: You do not appear to have the LAME library installed. Grab it from http://lame.sourceforge.net/" >&5 $as_echo "$as_me: error: You do not appear to have the LAME library installed. Grab it from http://lame.sourceforge.net/" >&2;} { (exit 1); exit 1; }; } fi if test "$lame" = "detect"; then lame=$lib fi fi { $as_echo "$as_me:$LINENO: checking for WavPack support" >&5 $as_echo_n "checking for WavPack support... " >&6; } # Check whether --with-wavpack was given. if test "${with_wavpack+set}" = set; then withval=$with_wavpack; wavpack="$withval" else wavpack="detect" fi if test "$wavpack" = "no"; then { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } else { $as_echo "$as_me:$LINENO: checking for WavpackOpenFileInput in -lwavpack" >&5 $as_echo_n "checking for WavpackOpenFileInput in -lwavpack... " >&6; } if test "${ac_cv_lib_wavpack_WavpackOpenFileInput+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lwavpack $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 WavpackOpenFileInput (); int main () { return WavpackOpenFileInput (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_wavpack_WavpackOpenFileInput=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_wavpack_WavpackOpenFileInput=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_wavpack_WavpackOpenFileInput" >&5 $as_echo "$ac_cv_lib_wavpack_WavpackOpenFileInput" >&6; } if test "x$ac_cv_lib_wavpack_WavpackOpenFileInput" = x""yes; then lib=yes else lib=no fi if test "$lib" = "yes"; then wavpack_LIBS=`pkg-config --libs wavpack` { $as_echo "$as_me:$LINENO: checking whether WavPack version >= 4.40.0" >&5 $as_echo_n "checking whether WavPack version >= 4.40.0... " >&6; } if pkg-config --exists 'wavpack >= 4.40.0'; then { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } cat >>confdefs.h <<\_ACEOF #define HAVE_WAVPACK 1 _ACEOF else lib="no" { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi fi if test "$lib" = "no" -a "$wavpack" = "yes"; then { { $as_echo "$as_me:$LINENO: error: You do not appear to have the WavPack library installed, or it is older than the required version (4.40.0). Grab it from http://www.wavpack.com" >&5 $as_echo "$as_me: error: You do not appear to have the WavPack library installed, or it is older than the required version (4.40.0). Grab it from http://www.wavpack.com" >&2;} { (exit 1); exit 1; }; } fi if test "$wavpack" = "detect"; then wavpack=$lib fi fi { $as_echo "$as_me:$LINENO: checking for LADSPA plugin support" >&5 $as_echo_n "checking for LADSPA plugin support... " >&6; } # Check whether --with-ladspa was given. if test "${with_ladspa+set}" = set; then withval=$with_ladspa; ladspa="$withval" else ladspa="detect" fi if test "$ladspa" = "no"; then { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } else { $as_echo "$as_me:$LINENO: checking for lrdf_init in -llrdf" >&5 $as_echo_n "checking for lrdf_init in -llrdf... " >&6; } if test "${ac_cv_lib_lrdf_lrdf_init+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-llrdf $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 lrdf_init (); int main () { return lrdf_init (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_lrdf_lrdf_init=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_lrdf_lrdf_init=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_lrdf_lrdf_init" >&5 $as_echo "$ac_cv_lib_lrdf_lrdf_init" >&6; } if test "x$ac_cv_lib_lrdf_lrdf_init" = x""yes; then lib=yes else lib=no fi if test "$lib" = "yes"; then { $as_echo "$as_me:$LINENO: checking whether liblrdf version >= 0.4.0" >&5 $as_echo_n "checking whether liblrdf version >= 0.4.0... " >&6; } if `pkg-config --exists 'lrdf >= 0.4.0'`; then { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } lrdf_LIBS=`pkg-config --libs lrdf` cat >>confdefs.h <<\_ACEOF #define HAVE_LADSPA 1 _ACEOF else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } lib="no" fi fi if test "$lib" = "no" -a "$ladspa" = "yes"; then { { $as_echo "$as_me:$LINENO: error: You do not appear to have the LRDF library installed (needed for LADSPA support). Grab it from http://sourceforge.net/projects/lrdf/" >&5 $as_echo "$as_me: error: You do not appear to have the LRDF library installed (needed for LADSPA support). Grab it from http://sourceforge.net/projects/lrdf/" >&2;} { (exit 1); exit 1; }; } fi if test "$ladspa" = "detect"; then ladspa=$lib fi fi { $as_echo "$as_me:$LINENO: checking for CDDA support" >&5 $as_echo_n "checking for CDDA support... " >&6; } # Check whether --with-cdda was given. if test "${with_cdda+set}" = set; then withval=$with_cdda; cdda="$withval" else cdda="detect" fi if test "$cdda" = "no"; then { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } else if test $win32 = "no" ; then { $as_echo "$as_me:$LINENO: checking for cdio_open in -lcdio" >&5 $as_echo_n "checking for cdio_open in -lcdio... " >&6; } if test "${ac_cv_lib_cdio_cdio_open+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcdio $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 cdio_open (); int main () { return cdio_open (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_cdio_cdio_open=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_cdio_cdio_open=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_cdio_cdio_open" >&5 $as_echo "$ac_cv_lib_cdio_cdio_open" >&6; } if test "x$ac_cv_lib_cdio_cdio_open" = x""yes; then lib=yes else lib=no fi else { $as_echo "$as_me:$LINENO: checking for cdio_open in -lcdio" >&5 $as_echo_n "checking for cdio_open in -lcdio... " >&6; } if test "${ac_cv_lib_cdio_cdio_open+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcdio -lwinmm $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 cdio_open (); int main () { return cdio_open (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_cdio_cdio_open=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_cdio_cdio_open=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_cdio_cdio_open" >&5 $as_echo "$ac_cv_lib_cdio_cdio_open" >&6; } if test "x$ac_cv_lib_cdio_cdio_open" = x""yes; then lib=yes else lib=no fi fi if test "$lib" = "yes"; then { $as_echo "$as_me:$LINENO: checking whether libcdio_paranoia version >= 0.76" >&5 $as_echo_n "checking whether libcdio_paranoia version >= 0.76... " >&6; } if `pkg-config --exists 'libcdio_paranoia >= 0.76'`; then cdda_CFLAGS=`pkg-config --cflags libcdio_paranoia` cdda_LIBS=`pkg-config --libs libcdio_paranoia` cat >>confdefs.h <<\_ACEOF #define HAVE_CDDA 1 _ACEOF { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } lib="no" fi fi if test "$lib" = "no" -a "$cdda" = "yes"; then { { $as_echo "$as_me:$LINENO: error: libcdio and/or libcdio_paranoia library not found or too old. Grab it from http://www.gnu.org/software/libcdio/" >&5 $as_echo "$as_me: error: libcdio and/or libcdio_paranoia library not found or too old. Grab it from http://www.gnu.org/software/libcdio/" >&2;} { (exit 1); exit 1; }; } fi if test "$cdda" = "detect"; then cdda=$lib fi fi { $as_echo "$as_me:$LINENO: checking for CDDB support" >&5 $as_echo_n "checking for CDDB support... " >&6; } # Check whether --with-cddb was given. if test "${with_cddb+set}" = set; then withval=$with_cddb; cddb="$withval" else cddb="detect" fi if test "$cddb" = "no"; then { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } else { $as_echo "$as_me:$LINENO: checking for cddb_new in -lcddb" >&5 $as_echo_n "checking for cddb_new in -lcddb... " >&6; } if test "${ac_cv_lib_cddb_cddb_new+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcddb $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 cddb_new (); int main () { return cddb_new (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_cddb_cddb_new=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_cddb_cddb_new=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_cddb_cddb_new" >&5 $as_echo "$ac_cv_lib_cddb_cddb_new" >&6; } if test "x$ac_cv_lib_cddb_cddb_new" = x""yes; then lib=yes else lib=no fi if test "$lib" = "yes"; then { $as_echo "$as_me:$LINENO: checking whether libcddb version >= 1.2.1" >&5 $as_echo_n "checking whether libcddb version >= 1.2.1... " >&6; } if `pkg-config --exists 'libcddb >= 1.2.1'`; then { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } cddb_LIBS=`pkg-config --libs libcddb` cat >>confdefs.h <<\_ACEOF #define HAVE_CDDB 1 _ACEOF { $as_echo "$as_me:$LINENO: checking for cddb_disc_get_revision in -lcddb" >&5 $as_echo_n "checking for cddb_disc_get_revision in -lcddb... " >&6; } if test "${ac_cv_lib_cddb_cddb_disc_get_revision+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcddb $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 cddb_disc_get_revision (); int main () { return cddb_disc_get_revision (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_cddb_cddb_disc_get_revision=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_cddb_cddb_disc_get_revision=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_cddb_cddb_disc_get_revision" >&5 $as_echo "$ac_cv_lib_cddb_cddb_disc_get_revision" >&6; } if test "x$ac_cv_lib_cddb_cddb_disc_get_revision" = x""yes; then libcddb_rev=yes else libcddb_rev=no fi if test "$libcddb_rev" = "yes"; then cat >>confdefs.h <<\_ACEOF #define LIBCDDB_REVISION 1 _ACEOF fi else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } lib="no" fi fi if test "$lib" = "no" -a "$cddb" = "yes"; then { { $as_echo "$as_me:$LINENO: error: CDDB library not found or too old (version < 1.2.1). Grab it from http://libcddb.sf.net/" >&5 $as_echo "$as_me: error: CDDB library not found or too old (version < 1.2.1). Grab it from http://libcddb.sf.net/" >&2;} { (exit 1); exit 1; }; } fi if test "$cddb" = "detect"; then cddb=$lib fi fi { $as_echo "$as_me:$LINENO: checking for iRiver iFP support" >&5 $as_echo_n "checking for iRiver iFP support... " >&6; } # Check whether --with-ifp was given. if test "${with_ifp+set}" = set; then withval=$with_ifp; ifp="$withval" else ifp="detect" fi if test "$ifp" = "no"; then { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } else { $as_echo "$as_me:$LINENO: checking for usb_init in -lusb" >&5 $as_echo_n "checking for usb_init in -lusb... " >&6; } if test "${ac_cv_lib_usb_usb_init+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lusb $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 usb_init (); int main () { return usb_init (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_usb_usb_init=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_usb_usb_init=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_usb_usb_init" >&5 $as_echo "$ac_cv_lib_usb_usb_init" >&6; } if test "x$ac_cv_lib_usb_usb_init" = x""yes; then lib=yes else lib=no fi if test "$lib" = "yes"; then { $as_echo "$as_me:$LINENO: checking for ifp_find_device in -lifp" >&5 $as_echo_n "checking for ifp_find_device in -lifp... " >&6; } if test "${ac_cv_lib_ifp_ifp_find_device+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lifp $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 ifp_find_device (); int main () { return ifp_find_device (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_ifp_ifp_find_device=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_ifp_ifp_find_device=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_ifp_ifp_find_device" >&5 $as_echo "$ac_cv_lib_ifp_ifp_find_device" >&6; } if test "x$ac_cv_lib_ifp_ifp_find_device" = x""yes; then lib=yes else lib=no fi if test "$lib" = "yes"; then ifp_LIBS="-lifp -lusb" cat >>confdefs.h <<\_ACEOF #define HAVE_IFP 1 _ACEOF fi if test "$lib" = "no" -a "$ifp" = "yes"; then { { $as_echo "$as_me:$LINENO: error: You do not appear to have the iFP driver library installed. Grab it from http://ifp-driver.sourceforge.net/" >&5 $as_echo "$as_me: error: You do not appear to have the iFP driver library installed. Grab it from http://ifp-driver.sourceforge.net/" >&2;} { (exit 1); exit 1; }; } fi fi if test "$ifp" = "detect"; then ifp=$lib fi fi { $as_echo "$as_me:$LINENO: checking for Systray support" >&5 $as_echo_n "checking for Systray support... " >&6; } # Check whether --with-systray was given. if test "${with_systray+set}" = set; then withval=$with_systray; systray="$withval" else systray="detect" fi if test "$systray" = "no"; then { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } else { $as_echo "$as_me:$LINENO: checking whether GTK+ version >= 2.10" >&5 $as_echo_n "checking whether GTK+ version >= 2.10... " >&6; } if pkg-config --exists 'gtk+-2.0 >= 2.10'; then { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } cat >>confdefs.h <<\_ACEOF #define HAVE_SYSTRAY 1 _ACEOF lib="yes" else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } lib="no" fi if test "$lib" = "no" -a "$systray" = "yes"; then { { $as_echo "$as_me:$LINENO: error: You need GTK+ version 2.10 or higher for systray support." >&5 $as_echo "$as_me: error: You need GTK+ version 2.10 or higher for systray support." >&2;} { (exit 1); exit 1; }; } fi if test "$systray" = "detect"; then systray=$lib fi fi { $as_echo "$as_me:$LINENO: checking for loop playback support" >&5 $as_echo_n "checking for loop playback support... " >&6; } # Check whether --with-loop was given. if test "${with_loop+set}" = set; then withval=$with_loop; loop="$withval" else loop="detect" fi if test "$loop" = "no"; then { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } else { $as_echo "$as_me:$LINENO: checking whether GTK+ version >= 2.8" >&5 $as_echo_n "checking whether GTK+ version >= 2.8... " >&6; } if pkg-config --exists 'gtk+-2.0 >= 2.8'; then { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } cat >>confdefs.h <<\_ACEOF #define HAVE_LOOP 1 _ACEOF lib="yes" else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } lib="no" fi if test "$lib" = "no" -a "$loop" = "yes"; then { { $as_echo "$as_me:$LINENO: error: You need GTK+ version 2.8 or higher for loop playback support." >&5 $as_echo "$as_me: error: You need GTK+ version 2.8 or higher for loop playback support." >&2;} { (exit 1); exit 1; }; } fi if test "$loop" = "detect"; then loop=$lib fi fi { $as_echo "$as_me:$LINENO: checking for podcast support" >&5 $as_echo_n "checking for podcast support... " >&6; } # Check whether --with-podcast was given. if test "${with_podcast+set}" = set; then withval=$with_podcast; podcast="$withval" else podcast="yes" fi if test "$podcast" = "no"; then { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } else cat >>confdefs.h <<\_ACEOF #define HAVE_PODCAST 1 _ACEOF { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:$LINENO: checking for Lua support" >&5 $as_echo_n "checking for Lua support... " >&6; } # Check whether --with-lua was given. if test "${with_lua+set}" = set; then withval=$with_lua; lua="$withval" else lua="detect" fi if test "$lua" = "no"; then { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } else { $as_echo "$as_me:$LINENO: checking for lua_load in -llua" >&5 $as_echo_n "checking for lua_load in -llua... " >&6; } if test "${ac_cv_lib_lua_lua_load+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-llua $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 lua_load (); int main () { return lua_load (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_lua_lua_load=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_lua_lua_load=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_lua_lua_load" >&5 $as_echo "$ac_cv_lib_lua_lua_load" >&6; } if test "x$ac_cv_lib_lua_lua_load" = x""yes; then lib=yes else lib=no fi if test "$lib" = "yes"; then lua_LIBS="-llua" cat >>confdefs.h <<\_ACEOF #define HAVE_LUA 1 _ACEOF else { $as_echo "$as_me:$LINENO: checking for lua_load in -llua5.1" >&5 $as_echo_n "checking for lua_load in -llua5.1... " >&6; } if test "${ac_cv_lib_lua5_1_lua_load+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-llua5.1 $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 lua_load (); int main () { return lua_load (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_lua5_1_lua_load=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_lua5_1_lua_load=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_lua5_1_lua_load" >&5 $as_echo "$ac_cv_lib_lua5_1_lua_load" >&6; } if test "x$ac_cv_lib_lua5_1_lua_load" = x""yes; then lib=yes else lib=no fi if test "$lib" = "yes"; then lua_LIBS="-llua5.1" cat >>confdefs.h <<\_ACEOF #define HAVE_LUA 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define LUA_HEADER_lua5_1 1 _ACEOF fi fi if test "$lib" = "no" -a "$lua" = "yes"; then { { $as_echo "$as_me:$LINENO: error: You do not appear to have the Lua 5.1 library installed. Grab it from http://www.lua.org/." >&5 $as_echo "$as_me: error: You do not appear to have the Lua 5.1 library installed. Grab it from http://www.lua.org/." >&2;} { (exit 1); exit 1; }; } fi if test "$lua" = "detect"; then lua=$lib fi fi # Compiler and linker variables AQUALUNG_SKINDIR="-DAQUALUNG_SKINDIR=\\\"$datadir/aqualung/skin\\\"" AQUALUNG_LOCALEDIR="-DAQUALUNG_LOCALEDIR=\\\"$datadir/locale\\\"" AQUALUNG_DATADIR="-DAQUALUNG_DATADIR=\\\"$datadir/aqualung\\\"" CFLAGS="$CFLAGS $BUILD_CFLAGS -Wall $PLATFORM_CFLAGS $AQUALUNG_SKINDIR $AQUALUNG_LOCALEDIR $AQUALUNG_DATADIR -D_GNU_SOURCE" CXXFLAGS="$CFLAGS" CPPFLAGS="$gtk_CFLAGS $glib_CFLAGS $xml_CFLAGS $alsa_CFLAGS $jack_CFLAGS $cdda_CFLAGS $pulse_CFLAGS" LIBS="decoder/libdecoder.a encoder/libencoder.a $gtk_LIBS $glib_LIBS $xml_LIBS $jack_LIBS $lrdf_LIBS $src_LIBS $alsa_LIBS $sndio_LIBS $oss_LIBS $sndfile_LIBS $flac_LIBS $ogg_LIBS $wavpack_LIBS $speex_LIBS $mad_LIBS $mod_LIBS $mpc_LIBS $mac_LIBS $lavc_LIBS $vorbisenc_LIBS $lame_LIBS $cdda_LIBS $cddb_LIBS $ifp_LIBS $PLATFORM_LIBS $z_LIBS $bz2_LIBS $lua_LIBS $pulse_LIBS" ac_config_files="$ac_config_files Makefile doc/Makefile skin/Makefile skin/dark/Makefile skin/default/Makefile skin/metal/Makefile skin/ocean/Makefile skin/plain/Makefile skin/woody/Makefile skin/no_skin/Makefile src/Makefile src/decoder/Makefile src/encoder/Makefile src/img/Makefile src/po/Makefile" 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:$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= ;; #( *) $as_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 test "x$cache_file" != "x/dev/null" && { $as_echo "$as_me:$LINENO: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} cat confcache >$cache_file else { $as_echo "$as_me:$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= 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. ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then { { $as_echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." >&5 $as_echo "$as_me: error: conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then { { $as_echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." >&5 $as_echo "$as_me: error: conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then { { $as_echo "$as_me:$LINENO: error: conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." >&5 $as_echo "$as_me: error: conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } 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:$LINENO: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} cat >$CONFIG_STATUS <<_ACEOF || ac_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} _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_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 # PATH needs CR # 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_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 if (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 # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false 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. 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); exit 1; } fi # Work around bugs in pre-3.0 UWIN ksh. for as_var in ENV MAIL MAILPATH do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # Required to use basename. 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 # Name of the executable. 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'` # CDPATH. $as_unset CDPATH as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line after each line using $LINENO; the second 'sed' # does the real work. The second script uses 'N' to pair each # line-number line with the line containing $LINENO, and appends # trailing '-' during substitution so that $LINENO is not a special # case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # scripts with optimization help from Paolo Bonzini. 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 { (exit 1); exit 1; }; } # 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 } if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in -n*) case `echo 'x\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. *) ECHO_C='\c';; esac;; *) ECHO_N='-n';; esac if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi 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 -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' 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=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # 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 # 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 aqualung $as_me 0.9beta11, which was generated by GNU Autoconf 2.63. 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 from templates according to the current configuration. Usage: $0 [OPTION]... [FILE]... -h, --help print this help, then exit -V, --version print version number and configuration settings, 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 ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_version="\\ aqualung config.status 0.9beta11 configured by $0, generated by GNU Autoconf 2.63, with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" Copyright (C) 2008 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' AWK='$AWK' 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=$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 ;; --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"` ;; esac CONFIG_FILES="$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 CONFIG_HEADERS="$CONFIG_HEADERS '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header { $as_echo "$as_me: error: ambiguous option: $1 Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; };; --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_echo "$as_me: error: unrecognized option: $1 Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *) ac_config_targets="$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 # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" _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" ;; "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; "skin/Makefile") CONFIG_FILES="$CONFIG_FILES skin/Makefile" ;; "skin/dark/Makefile") CONFIG_FILES="$CONFIG_FILES skin/dark/Makefile" ;; "skin/default/Makefile") CONFIG_FILES="$CONFIG_FILES skin/default/Makefile" ;; "skin/metal/Makefile") CONFIG_FILES="$CONFIG_FILES skin/metal/Makefile" ;; "skin/ocean/Makefile") CONFIG_FILES="$CONFIG_FILES skin/ocean/Makefile" ;; "skin/plain/Makefile") CONFIG_FILES="$CONFIG_FILES skin/plain/Makefile" ;; "skin/woody/Makefile") CONFIG_FILES="$CONFIG_FILES skin/woody/Makefile" ;; "skin/no_skin/Makefile") CONFIG_FILES="$CONFIG_FILES skin/no_skin/Makefile" ;; "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; "src/decoder/Makefile") CONFIG_FILES="$CONFIG_FILES src/decoder/Makefile" ;; "src/encoder/Makefile") CONFIG_FILES="$CONFIG_FILES src/encoder/Makefile" ;; "src/img/Makefile") CONFIG_FILES="$CONFIG_FILES src/img/Makefile" ;; "src/po/Makefile") CONFIG_FILES="$CONFIG_FILES src/po/Makefile" ;; *) { { $as_echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 $as_echo "$as_me: error: invalid argument: $ac_config_target" >&2;} { (exit 1); exit 1; }; };; 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= trap 'exit_status=$? { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status ' 0 trap '{ (exit 1); exit 1; }' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || { $as_echo "$as_me: cannot create a temporary directory in ." >&2 { (exit 1); exit 1; } } # 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=' ' 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 {' >"$tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 $as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } 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_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 $as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } 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_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 $as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } 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 >>"\$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 >>"\$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 < "$tmp/subs1.awk" > "$tmp/subs.awk" \ || { { $as_echo "$as_me:$LINENO: error: could not setup config files machinery" >&5 $as_echo "$as_me: error: could not setup config files machinery" >&2;} { (exit 1); exit 1; }; } _ACEOF # VPATH may cause trouble with some makes, so we remove $(srcdir), # ${srcdir} and @srcdir@ 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[ ]*=/{ s/:*\$(srcdir):*/:/ s/:*\${srcdir}:*/:/ s/:*@srcdir@:*/:/ s/^\([^=]*=[ ]*\):*/\1/ s/:*$// 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 >"$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_t=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_t"; then break elif $ac_last_try; then { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_HEADERS" >&5 $as_echo "$as_me: error: could not make $CONFIG_HEADERS" >&2;} { (exit 1); exit 1; }; } 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_echo "$as_me:$LINENO: error: could not setup config headers machinery" >&5 $as_echo "$as_me: error: could not setup config headers machinery" >&2;} { (exit 1); exit 1; }; } 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_echo "$as_me:$LINENO: error: invalid tag $ac_tag" >&5 $as_echo "$as_me: error: invalid tag $ac_tag" >&2;} { (exit 1); exit 1; }; };; :[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="$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_echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 $as_echo "$as_me: error: cannot find input file: $ac_f" >&2;} { (exit 1); exit 1; }; };; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac ac_file_inputs="$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:$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 >"$tmp/stdin" \ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 $as_echo "$as_me: error: could not create $ac_file" >&2;} { (exit 1); exit 1; }; } ;; 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" case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { 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_echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 $as_echo "$as_me: error: cannot create directory $as_dir" >&2;} { (exit 1); exit 1; }; }; } 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:$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 "$tmp/subs.awk" >$tmp/out \ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 $as_echo "$as_me: error: could not create $ac_file" >&2;} { (exit 1); exit 1; }; } test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:$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 "$tmp/stdin" case $ac_file in -) cat "$tmp/out" && rm -f "$tmp/out";; *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";; esac \ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 $as_echo "$as_me: error: could not create $ac_file" >&2;} { (exit 1); exit 1; }; } ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" } >"$tmp/config.h" \ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 $as_echo "$as_me: error: could not create $ac_file" >&2;} { (exit 1); exit 1; }; } if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:$LINENO: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$tmp/config.h" "$ac_file" \ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 $as_echo "$as_me: error: could not create $ac_file" >&2;} { (exit 1); exit 1; }; } fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \ || { { $as_echo "$as_me:$LINENO: error: could not create -" >&5 $as_echo "$as_me: error: could not create -" >&2;} { (exit 1); exit 1; }; } fi # Compute "$ac_file"'s index in $config_headers. _am_arg="$ac_file" _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || $as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$_am_arg" : 'X\(//\)[^/]' \| \ X"$_am_arg" : 'X\(//\)$' \| \ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$_am_arg" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'`/stamp-h$_am_stamp_count ;; :C) { $as_echo "$as_me:$LINENO: executing $ac_file commands" >&5 $as_echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || # Autoconf 2.62 quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named `Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`$as_dirname -- "$mf" || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ X"$mf" : 'X\(//\)$' \| \ X"$mf" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running `make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`$as_dirname -- "$file" || $as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$file" : 'X\(//\)[^/]' \| \ X"$file" : 'X\(//\)$' \| \ X"$file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` { as_dir=$dirpart/$fdir case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { 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_echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 $as_echo "$as_me: error: cannot create directory $as_dir" >&2;} { (exit 1); exit 1; }; }; } # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done ;; esac done # for ac_tag { (exit 0); exit 0; } _ACEOF chmod +x $CONFIG_STATUS ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || { { $as_echo "$as_me:$LINENO: error: write failure creating $CONFIG_STATUS" >&5 $as_echo "$as_me: error: write failure creating $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } # 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 || { (exit 1); exit 1; } fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:$LINENO: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi echo "----------------------------------------------------------------------" echo " Configuration summary" echo " =====================" echo echo " Build type / target platform : $buildtype / $platform" echo echo " Optional features:" echo " LADSPA plugin support : $ladspa" echo " CDDA (Audio CD) support : $cdda" echo " CDDB support : $cddb" echo " Sample Rate Converter support : $src" echo " iRiver iFP driver support : $ifp" echo " Loop playback support : $loop" echo " Systray support : $systray" echo " Podcast support : $podcast" echo " Lua (prog. title format) support : $lua" echo echo " Decoding support:" echo " sndfile (WAV, AIFF, AU, etc.) : $sndfile" echo " Free Lossless Audio Codec (FLAC) : $flac" echo " Ogg Vorbis : $ogg" echo " Ogg Speex : $speex" echo " MPEG Audio (MPEG 1-2.5 Layer I-III) : $mpeg" echo " MOD Audio (MOD, S3M, XM, IT, etc.) : $mod" echo " Musepack : $mpc" echo " Monkey's Audio Codec : $mac" echo " WavPack : $wavpack" echo " LAVC (AC3, AAC, WavPack, WMA, etc.) : $lavc" echo echo " Encoding support:" echo " sndfile (WAV) : $sndfile" echo " Free Lossless Audio Codec (FLAC) : $flac" echo " Ogg Vorbis : $vorbisenc" echo " LAME (MP3) : $lame" echo echo " Output driver support:" echo " sndio Audio : $sndio" echo " OSS Audio : $oss" echo " ALSA Audio : $alsa" echo " JACK Audio Server : $jack" echo " PulseAudio : $pulse" echo " Win32 Sound API : $win32" echo echo "----------------------------------------------------------------------" aqualung-0.9beta11/AUTHORS0000644000175000001440000000075311243311604012162 00000000000000AUTHORS Core design, engineering & programming: Tom Szilagyi Skin support, look & feel, GUI hacks: Peter Szilagyi Programming, GUI engineering: Tomasz Maka OpenBSD compatibility, metadata tweaks: Jeremy Evans CONTRIBUTORS Maarten Maathuis : Transition to FLAC API 8. Hong Jen Yee (PCMan) : PulseAudio support aqualung-0.9beta11/COPYING0000644000175000001440000004311010612341736012147 00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. aqualung-0.9beta11/ChangeLog0000644000175000001440000005344711331333173012677 000000000000002010-01-31 Tom Szilagyi * Aqualung 0.9beta11 http://aqualung.factorial.hu * Add PulseAudio support as contributed by PCMan plus a few minor fixes. * Added option for starting Aqualung hidden in tray. Useful when running Aqualung automatically after login. * Implement auto roll to active track functionality. Thanks to Chris Craig for the excellent patch. * Support new Musepack API (patch by Yavor Doganov) * New keybinding: Ctrl-S to stop after currently playing song has ended. Thanks to cobines for the patch. * Add support for more versatile mouse-systray interaction. Thanks to cobines for the excellent patch. * Added support for new GtkTooltip API (since 2.12). Fixed tooltip disappearing issue because of too frequent tooltip updates. * Automatically add/remove stores when they become available or disappear (most likely due to mount/unmount operations). Modified stores will not be removed automatically. * Add support for an application_title lua function separate from the playlist_title lua function, so that the window title and the main title label of the player is configurable from Lua. * Don't require restart to update programmable title format file * Don't use sndfile's Ogg decoder (always use native Ogg library) * Fix FFmpeg headers detection in configure script * Fix compiler warnings on 64 bit. Thanks to Zoltan Kovacs for the patch. * Fix crash on 64 bit when Aqualung is compiled without SRC support and file contains metadata. Thanks to Zoltan Kovacs for tracking the problem and providing the patch. * Fixed crash when pasting into playlist without copying first (empty clipboard). * Fix a suspected regression: space toggles state of combined play/pause button when a file is loaded. * Fix lockup at end of playlist. * Fixed a crash that occurred when clicked on a picture of a file in the File Info dialog and the file format did not support metadata. * Fix playlist column size allocation by eliminating manual/delayed calculations and utilizing the built-in COLUMN_AUTOSIZE feature instead. * Fix crash when invoking the File Info dialog for an MPEG internet radio. * Fix inversion of enabled/diasbled state of tooltips. * Fix crash when loading .m3u with invalid filename. * Updated translations: German, Hungarian, Russian, Ukrainian * New translations: Japanese by Norihiro Yoneda French by Julien Lavergne * Up-to-date user documentation 2009-02-08 Tom Szilagyi * Aqualung 0.9beta10 http://aqualung.factorial.hu * Add programmable title format support. This commit embeds a Lua interpreter inside of Aqualung for the purpose of allowing the user full control over the title format. It allows the user to use any metadata field that Aqualung recognizes, as well as a few fields from the file info in order to compose a title field. See the documentation update included in this release for usage information for this feature. * Loop playback enhancements: New key bindings '<' and '>' for adjusting loop range start and end (respectively) to the current playing position. Active only when track repeat mode is on and a track is currently playing or paused. Added tooltip showing loop range in percentage and time (if there is a track loaded). Tooltips must be globally enabled for this feature. * Allow the systray to be disabled even if support is compiled in. * Add support for saving single playlists in M3U format. If the playlist file name ends with .m3u, it will save in M3U format (one filename per line) instead of the Aqualung XML format. This only affects the logic around saving single playlists; if you save all playlists at once, it will always use the XML format, because the M3U format does not support multiple playlists. * Add support for sndio backend, bringing the total number of backends to five. libsndio was recently introduced in OpenBSD as a simple audio API that supports OpenBSD's builtin sound server, aucat. * Add playlist context menu option 'Roll to active song'. * Optionally combine Play and Pause buttons into a single button. * Fix gapless MPEG audio playback (correct offset calculation) when ID3v2 tag is present. * Export can now copy files instead of reencoding them using the new target format "Copy". * A subset of input files can be forced to be copied instead of being reencoded. There are two criteria for this: when the source file is already in the target format, and when the source file matches any of a comma-separated list of wildchards (similarly to the builder exclusion list). Both options can be enabled/disabled from the Export dialog. * Handle HTTP/1.0 responses. * When updating all feeds, insert 1 second delay between individual feeds. * Added right-click menu items for adding only new podcasts to playlist. * Music Stores can now use relative paths instead of absolute ones, allowing users to mount the same collection on different mount points (just one use case). Implementation is based on the patch by Russell Johnston, big thanks for both the idea and the contribution. A checkbox for toggling this feature is added to the Edit Store dialog (accessible via the right-click menu of stores). * All filenames use the GLib filename encoding instead of locale encoding. This is the proper and official way of doing it; if you have issues using filenames with special characters, consider setting the G_FILENAME_ENCODING or G_BROKEN_FILENAMES environment variables. If you are using an UTF-8 locale (a very wise choice), you have nothing to worry about. * Add extra check for mad.h presence to configure. * New store builder option to automatically remove non-existing files from the store. It is disabled by default. * Added new Swedish translation by Niklas Grahn. * Numerous minor bugfixes. 2008-02-10 Tom Szilagyi * Aqualung 0.9beta9.1 http://aqualung.factorial.hu This is a bugfix, stability and performance oriented release also containing a few updates to existing functionality. By using this version, your Aqualung will be more stable, and in some cases significantly faster. All users are encouraged to upgrade. The project homepage has moved to http://aqualung.factorial.hu Please upgrade your pointers and bookmarks. Notable changes: * Playlist code refactoring for improved performance. Please note that incompatible changes have been made to the playlist format: this means that your old playlists won't be parsed, you'll have to re-create them. (NOTE: Music Store contents are unaffected. If we ever change the Music Store format in a backward-incompatible way, we will provide tools to migrate your precious store data.) * Fix threading problems that caused random crashes for some users. * Fix lurking bug that sometimes resulted in getting stuck at the beginning of a track when Sinc interpolator sample rate converters were used. * Modified the way of opening ALSA output to achieve non-exclusive driver access. * New, more versatile title string generating templates. Make sure to check the documentation. * Added option to periodically save playlist. * Several fixes concerning command line file and playlist loading, esp. with the -L flag. * Better metadata handling for external files in playlist. * Increment CDDB revision number on resubmitting an existing disc. This is essential for correcting existing CDDB entries, otherwise the CDDB server rejects the submission. The latest CVS version from http://libcddb.sf.net is required for this to work (Aqualung-Win32 is built with this version). * OpenBSD-related portability fixes. Aqualung should now compile cleanly and be fully functional OOTB on OpenBSD 4.2. * Updated German, Hungarian and Italian translations. Added Russian translation. 2007-12-19 Tom Szilagyi * Aqualung 0.9beta9 http://aqualung.sf.net This is a major release bringing significant new functionality and many important fixes. All users are encouraged to upgrade. As always, the up-to-date User Manual is available at: http://aqualung.sourceforge.net/?tab=docs Major additions: * Fundamentally new Metadata system, using native decoders and private code instead of TagLib to provide complete support for reading and writing metadata, including ID3v1, ID3v2.3, ID3v2.4, APE, Ogg Xiph comments and FLAC picture frames, as well as read-only support for ReplayGain in Musepack stream data and various metadata received in internet radio streams. Aqualung also provides a batch tagger facility to quickly propagate Music Store metadata to file metadata. * Support for podcasts. Aqualung can subscribe to RSS and Atom audio podcasts, and automatically download and add new files to the Music Store. Optional limits for the age, size and number of downloaded files can be set. * Support for exporting files from Music Store or Playlist with audio transcoding and intelligent metadata transfer. Useful for burning your favourite tracks to CD, filling your portable player, etc. * Aqualung now compiles and runs on OpenBSD. * Smoother skin changing. * Option to disable skin support (for themed environments). * Lots of fixes, cleanups & refactoring. DROPPED DEPENDENCIES: * TagLib is not used anymore. 2007-07-07 Tom Szilagyi * Aqualung 0.9beta8 http://aqualung.sf.net This is a major release bringing significant new functionality and many important fixes. All users are encouraged to upgrade. Major additions: * Support for internet radio streams using Ogg Vorbis and MP3 audio encoding. * Tabbed playlist support, very similar in concept to the tabbed browsing feature of Firefox. Smaller fixes, rewrites and additions have been also done, particularly to the following areas: * Cut/copy/paste functionality implemented in playlist. Works with the usual Ctrl-X/C/V key combinations. * MPEG decoder: more robust in case of corrupt UBR files. * Command-line local and remote file loading. * M3U and PLS parsers. * HTTP proxy handling. * RVA handling: now supports setting a default value for unmeasured tracks. * Icons and Documentation. * Added Italian translation. 2007-02-18 Tom Szilagyi * Aqualung 0.9beta7.1 http://aqualung.sf.net This is a bugfix release, for some important fixes that were found due to the greater user coverage after the beta7 release. * Fixed drag and drop from external applications. * Remove selected tracks and invert selection in Playlist are now fast (optimized and improved). * Shortcut 'A' (show active song) doesn't interfere with CTRL+A (select all). * Added checks for NULL pointers as a workaround for a TagLib bug. * Added native WavPack decoder contributed by Maarten Maathuis. 2007-02-05 Tom Szilagyi * Aqualung 0.9beta7 http://aqualung.sf.net This release introduces important new features and bugfixes. Main reasons for upgrading: * CD Audio support, complete with CDDB, CD-Text, etc. You can play Audio CDs directly, or rip them to WAV, FLAC, Ogg Vorbis or MP3 (CBR/VBR, gapless via LAME) complete with tagging, on the fly. * Revamped Music Store Builder: better operation, greater flexibility. * Support FFmpeg library enabling the recognition of numerous formats e.g. AC3, AAC, WMA, WavPack, and the soundtrack of many video files. * Replaygain support for APEv2 tags. * Ability to set looping range when looping a single file. Should be useful for people playing along a recording, trying to learn phrases of a song. * Adding music to the playlist is now a non-blocking, interruptible background operation. * Drag-and-drop files from external sources (Nautilus, Konqueror, etc) into the Aqualung playlist. * Several critical memory leak fixes. * Numerous GUI refinements; fixed some rare bugs in engine, too. * Support for building against the new FLAC 1.1.3 API. * Aqualung operates correctly on bigendian systems (32 and 64 bit). * Running natively on MS Windows. A port of TAP-plugins is included in the installer. See http://aqualung.sf.net/win32 for more. NEW LIBRARY DEPENDENCIES: All of these are optional; Aqualung will build without them, disabling the functionality they provide. * libcdio >= 0.76 is required for CD audio support. http://www.gnu.org/software/libcdio/ * libvorbisenc for ripping into Ogg Vorbis. http://www.xiph.org/ogg/vorbis/ * libmp3lame for ripping into MP3. http://lame.sourceforge.net/ 2006-10-03 Tom Szilagyi * Aqualung 0.9beta6 http://aqualung.sf.net This release introduces a fair number of substantial improvements: * Music Store builder: automatically build a Music Store by scanning the files on disk. Perform CDDB lookups & extract metadata on the fly. * MPEG decoder enhancements: robust file recognition, VBR and UBR file support, frame-accurate seeking, true gapless playback via eliminating encoder padding+delay read from LAME headers. * Fully revamped metadata support using TagLib. The result is a more complete implementation also supporting APE tags in Musepack files. * Automatic output driver detection: ability to startup without command line arguments (using default driver parameters). * Systray (a.k.a. Notification Area) support. * Handling of compressed MOD files (.gz and .bz2). * Resolved issue with JACK memory locking (which previously resulted in runaway memory consumption). * Aqualung compiles & runs under FreeBSD and Cygwin. NEW LIBRARY DEPENDENCIES: * TagLib >= 1.4 is now required for metadata support. http://developer.kde.org/~wheeler/taglib.html * GTK+ >= 2.10 is needed for the (optional) Systray support. DROPPED DEPENDENCIES: * libid3tag library is not required anymore (succeeded by TagLib). 2006-06-30 Tom Szilagyi * Aqualung 0.9beta5 http://aqualung.sf.net This is a new milestone release after 17 months of silent development. Large parts of the program have been rewritten, refactored, fixed, etc. A multitude of new features have been added to the software, which now weighs into Open Source with about 30,000 lines of GPL'ed source code written by a handful of free-time developers (no, you won't need your whole hand). It won't make too much sense to precisely list every change made to the sources during this period - the list would be prohibitively lengthy. For the curious, the mailing list archive is recommended. The most important, high-level changes are summarized below. * Group CDs in the Playlist via "Album mode". Shuffle between records but play their contents in order! * Statusbars in Playlist and Music Store display statistics and other data. * Multiple Music Stores are supported - useful for separate genres, file formats or for music mounted from different file servers via NFS. * CDDB support! * iFP driver support for integrating with iRiver HW players! * Completely reworked Settings dialog, the new control center! * Embed Playlist into Main window for a more compact look! * Search facility for Music Store and Playlist. * Add support for Musepack (via libmpcdec), Monkey's Audio, Ogg Speex. * Rudimentary album art (cover display) support. * RVA-related work, improved metadata support. * Fixed a boatload of bugs concerning cyrillic filenames, etc. * MP3 improvements (file recognition, clipping, seeking...) * Better fault tolerance in Ogg Vorbis decoder. * Various GUI fixes, new command line options, etc, etc. * Improved build system for skins, icons, etc. * New skins (Ocean, Plain), new Logo (see About box)! ;-) * Better RT behaviour with Jack output * Compiles and runs on AMD64 (thanks to Mark Knecht for testing)! 2005-01-30 Tom Szilagyi * Aqualung 0.9beta4.1 This minor release fixes a crashing bug discovered shortly after the release of beta4. No new functionality was added. 2005-01-28 Tom Szilagyi * Aqualung 0.9beta4 http://aqualung.sf.net INCOMPATIBLE CHANGES: [none] NEW LIBRARY DEPENDENCIES: * liblrdf 0.4.0 is now required (was: 0.3.7) http://lrdf.sourceforge.net * libid3tag library required if you want ID3v2 support http://sourceforge.net/project/showfiles.php?group_id=12349 MAJOR CHANGES: * Internationalization support via gettext. German, Hungarian and Ukrainian translations available; new translations for any language happily accepted at any time * Implemented read support for .m3u and .pls playlist formats. The formats are distinguished using file extensions (case insensitive). Now you can supply .m3u or .pls files on the command line, or select one in the Load/Enqueue Playlist option of the playlist window's popup menu. Aqualung does not implement shoutcast ATM, so URLs will be simply discarded. * new 'File info' dialog box (accessible from the Music Store and the Playlist) displays FLAC stream metadata, Ogg Vorbis comments and ID3v2 tags found in the soundfiles. * playback RVA support. Aqualung has its own system for this, from volume level calculation of files in the Music Store, to adjusting the dynamics characteristics to your listening environment. * Import FLAC/Vorbis/ID3v2 metadata into the Music Store via the 'File info' dialog accessed from the Music Store. On the right side of the tag data fields, there are buttons to import every piece of information into relevant fields of the Music Store database. In particular, ID3v2.4 RVA tags can be imported as manual RVA adjustment values. * many changes to enable displaying track lengths and RVA values in the Playlist. You can configure the column order in the Playlist, and displaying Lengths and RVA values can be turned off. (Track lengths are shown on the right side, RVA is hidden by default.) * New Settings notebook page "Playlist" for configuring the behavior of this stuff. * new remote option to terminate an already running instance: the -Q or --quit option will cause the instance specified by -N, or the 0-th instance by default, to terminate (just as if you exited it normally). * added support for remotely changing the volume via the --volume or -V option. Defaults to the 0th running instance. * major code rearrangement of Aqualung Core (file decoder is abstracted, runnable in multiple instances at the same time, separated in file_decoder.[ch]) * added all four basic aqualung skins (dark, default, metal, woody) to CVS. These are automatically available after a make install from now, no need to install them separately. * also, the skins have been updated to match recent new dialogs & widgets * docs update (manpage, HTML) for the beta4 release. MINOR CHANGES: * ./configure won't stop anymore if an optional library is missing, unless --with-PACKAGE is applied. Closes mantis bug #16. * Changes to the interface for adding files to the playlist locally or remotely * Implemented conversion from/to UTF8/locale charset. (Closes mantis bug #7). Note: please set the environment variable G_BROKEN_FILENAMES or G_FILENAME_ENCODING appropriately if your filesystem encoding is not UTF8. See http://developer.gimp.org/api/2.0/glib/glib-running.html for details. * Starting playback of a new track via double-clicking on it in the playlist is now allowed when another track is being paused. (Closes bug #14) * Implemented cue-from-paused-state functions (re: bug #15) as suggested by SGh. * Added check for pkg-config -exist "jack" to configure.ac. Up till now, the ./configure script failed to detect the condition when the jack daemon is present, but development files are not. (As if you installed JACK from a distro, but forgot to include the corresponding -dev package.) * Implement trashlist object to collect and eventually free pieces of memory that are malloc'ed in an ad-hoc manner in different places, but need to be freed sometime. * Use the trashlist to collect and free some memory that was leaked until now in LADSPA plugin dialogs and the File info dialog. * renamed "Options" dialog to "Settings". This name better suits the purpose of this dialog. * minor rearrangement of "Add Artist", "Edit Artist", "Add Record", "Edit Record", "Add Track" & "Edit Track" dialogs, hopefully for the better. * changed About box font to normal (Courier is not always available) * Workaround LADSPA plugin loading bug on ReiserFS (use the --with-brokenplfix configure option) 2004-09-09 Tom Szilagyi * Added support for remotely controlling running instances as well as adding new files to their playlists. * Added support for adding files to playlist from the command line. * Display instance numbers in title bar (except for the first instance) * Minor fixes to the internal cueing logic. * Aqualung 0.9beta3 2004-09-06 Tom Szilagyi * Added support for MOD file formats (MOD, S3M, XM, IT, etc.) * When using JACK output with custom client name, this client name is displayed in the title bar of the main window * Aqualung 0.9beta2 2004-09-03 Tom Szilagyi * First public release: Aqualung 0.9beta1 aqualung-0.9beta11/INSTALL0000644000175000001440000001722710612341736012157 00000000000000Basic Installation ================== These are generic installation instructions. 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, a file `config.cache' that saves the results of its tests to speed up reconfiguring, and a file `config.log' containing compiler output (useful mainly for debugging `configure'). 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 at some point `config.cache' contains results you don't want to keep, you may remove or edit it. The file `configure.in' is used to create `configure' by a program called `autoconf'. You only need `configure.in' 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. If you're using `csh' on an old version of System V, you might need to type `sh ./configure' instead to prevent `csh' from trying to execute `configure' itself. Running `configure' takes awhile. 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. 4. Type `make install' to install the programs and any data files and documentation. 5. 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. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the `configure' script does not know about. You can give `configure' initial values for variables by setting them in the environment. Using a Bourne-compatible shell, you can do that on the command line like this: CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure Or on systems that have the `env' program, you can do it like this: env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure 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 must use a version of `make' that supports the `VPATH' variable, such as 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 `..'. If you have to use a `make' that does not supports the `VPATH' variable, you have 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. Installation Names ================== By default, `make install' will install the package's files in `/usr/local/bin', `/usr/local/man', etc. You can specify an installation prefix other than `/usr/local' by giving `configure' the option `--prefix=PATH'. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you give `configure' the option `--exec-prefix=PATH', the package will use PATH as the prefix for installing programs and libraries. Documentation and other data files will still use the regular prefix. In addition, if you use an unusual directory layout you can give options like `--bindir=PATH' 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. 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'. Optional Features ================= 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. Specifying the System Type ========================== There may be some features `configure' can not figure out automatically, but needs to determine by the type of host the package will run on. Usually `configure' can figure that out, but if it prints a message saying it can not guess the host type, give it the `--host=TYPE' option. TYPE can either be a short name for the system type, such as `sun4', or a canonical name with three fields: CPU-COMPANY-SYSTEM 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 host type. If you are building compiler tools for cross-compiling, you can also use the `--target=TYPE' option to select the type of system they will produce code for and the `--build=TYPE' option to select the type of system on which you are compiling the package. 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. Operation Controls ================== `configure' recognizes the following options to control how it operates. `--cache-file=FILE' Use and save the results of the tests in FILE instead of `./config.cache'. Set FILE to `/dev/null' to disable caching, for debugging `configure'. `--help' Print a summary of the options to `configure', and exit. `--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. `--version' Print the version of Autoconf used to generate the `configure' script, and exit. `configure' also accepts some other, not widely useful, options. aqualung-0.9beta11/NEWS0000644000175000001440000000000010612341736011602 00000000000000aqualung-0.9beta11/compile0000755000175000001440000000717311126213353012475 00000000000000#! /bin/sh # Wrapper for compilers which do not understand `-c -o'. scriptversion=2005-05-14.22 # Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc. # Written by Tom Tromey . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # 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 file is maintained in Automake, please report # bugs to or send patches to # . case $1 in '') echo "$0: No command. Try \`$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: compile [--help] [--version] PROGRAM [ARGS] Wrapper for compilers which do not understand `-c -o'. Remove `-o dest.o' from ARGS, run PROGRAM with the remaining arguments, and rename the output as expected. If you are trying to build a whole package this is not the right script to run: please start by reading the file `INSTALL'. Report bugs to . EOF exit $? ;; -v | --v*) echo "compile $scriptversion" exit $? ;; esac ofile= cfile= eat= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as `compile cc -o foo foo.c'. # So we strip `-o arg' only if arg is an object. eat=1 case $2 in *.o | *.obj) ofile=$2 ;; *) set x "$@" -o "$2" shift ;; esac ;; *.c) cfile=$1 set x "$@" "$1" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -z "$ofile" || test -z "$cfile"; then # If no `-o' option was seen then we might have been invoked from a # pattern rule where we don't need one. That is ok -- this is a # normal compilation that the losing compiler can handle. If no # `.c' file was seen then we are probably linking. That is also # ok. exec "$@" fi # Name of file we expect compiler to create. cofile=`echo "$cfile" | sed -e 's|^.*/||' -e 's/\.c$/.o/'` # Create the lock directory. # Note: use `[/.-]' here to ensure that we don't use the same name # that we are using for the .o file. Also, base the name on the expected # object file name, since that is what matters with a parallel build. lockdir=`echo "$cofile" | sed -e 's|[/.-]|_|g'`.d while true; do if mkdir "$lockdir" >/dev/null 2>&1; then break fi sleep 1 done # FIXME: race condition here if user kills between mkdir and trap. trap "rmdir '$lockdir'; exit 1" 1 2 15 # Run the compile. "$@" ret=$? if test -f "$cofile"; then mv "$cofile" "$ofile" elif test -f "${cofile}bj"; then mv "${cofile}bj" "$ofile" fi rmdir "$lockdir" exit $ret # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-end: "$" # End: aqualung-0.9beta11/depcomp0000755000175000001440000002752510612341736012505 00000000000000#! /bin/sh # depcomp - compile a program generating dependencies as side-effects # Copyright 1999, 2000 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # 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. # Originally written by Alexandre Oliva . if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # `libtool' can also be set to `yes' or `no'. depfile=${depfile-`echo "$object" | sed 's,\([^/]*\)$,.deps/\1,;s/\.\([^.]*\)$/.P\1/'`} tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ## The second -e expression handles DOS-style file names with drive letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the `deleted header file' problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. tr ' ' ' ' < "$tmpdepfile" | ## Some versions of gcc put a space before the `:'. On the theory ## that the space means something, we add a space to the output as ## well. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like `#:fec' to the end of the # dependency line. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ tr ' ' ' ' >> $depfile echo >> $depfile # The second pass generates a dummy entry for each header file. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> $depfile else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. This file always lives in the current directory. # Also, the AIX compiler puts `$object:' at the start of each line; # $object doesn't have directory information. stripped=`echo "$object" | sed -e 's,^.*/,,' -e 's/\(.*\)\..*$/\1/'` tmpdepfile="$stripped.u" outname="$stripped.o" if test "$libtool" = yes; then "$@" -Wc,-M else "$@" -M fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi if test -f "$tmpdepfile"; then # Each line is of the form `foo.o: dependent.h'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile" sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile" else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; tru64) # The Tru64 AIX compiler uses -MD to generate dependencies as a side # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in `foo.d' instead, so we check for that too. # Subdirectories are respected. tmpdepfile1="$object.d" tmpdepfile2=`echo "$object" | sed -e 's/.o$/.d/'` if test "$libtool" = yes; then "$@" -Wc,-MD else "$@" -MD fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi if test -f "$tmpdepfile1"; then tmpdepfile="$tmpdepfile1" else tmpdepfile="$tmpdepfile2" fi if test -f "$tmpdepfile"; then sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" # That's a space and a tab in the []. sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" else echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the proprocessed file to stdout, regardless of -o, # because we must use -o when running libtool. test -z "$dashmflag" && dashmflag=-M ( IFS=" " case " $* " in *" --mode=compile "*) # this is libtool, let us make it quiet for arg do # cycle over the arguments case "$arg" in "--mode=compile") # insert --quiet before "--mode=compile" set fnord "$@" --quiet shift # fnord ;; esac set fnord "$@" "$arg" shift # fnord shift # "$arg" done ;; esac "$@" $dashmflag | sed 's:^[^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" ) & proc=$! "$@" stat=$? wait "$proc" if test "$stat" != 0; then exit $stat; fi rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" tr ' ' ' ' < "$tmpdepfile" | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) # X makedepend ( shift cleared=no for arg in "$@"; do case $cleared in no) set ""; shift cleared=yes esac case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift;; -*) ;; *) set fnord "$@" "$arg"; shift;; esac done obj_suffix="`echo $object | sed 's/^.*\././'`" touch "$tmpdepfile" ${MAKEDEPEND-makedepend} 2>/dev/null -o"$obj_suffix" -f"$tmpdepfile" "$@" ) & proc=$! "$@" stat=$? wait "$proc" if test "$stat" != 0; then exit $stat; fi rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" tail +3 "$tmpdepfile" | tr ' ' ' ' | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the proprocessed file to stdout, regardless of -o, # because we must use -o when running libtool. ( IFS=" " case " $* " in *" --mode=compile "*) for arg do # cycle over the arguments case $arg in "--mode=compile") # insert --quiet before "--mode=compile" set fnord "$@" --quiet shift # fnord ;; esac set fnord "$@" "$arg" shift # fnord shift # "$arg" done ;; esac "$@" -E | sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | sed '$ s: \\$::' > "$tmpdepfile" ) & proc=$! "$@" stat=$? wait "$proc" if test "$stat" != 0; then exit $stat; fi rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the proprocessed file to stdout, regardless of -o, # because we must use -o when running libtool. ( IFS=" " case " $* " in *" --mode=compile "*) for arg do # cycle over the arguments case $arg in "--mode=compile") # insert --quiet before "--mode=compile" set fnord "$@" --quiet shift # fnord ;; esac set fnord "$@" "$arg" shift # fnord shift # "$arg" done ;; esac "$@" -E | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" ) & proc=$! "$@" stat=$? wait "$proc" if test "$stat" != 0; then exit $stat; fi rm -f "$depfile" echo "$object : \\" > "$depfile" . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" echo " " >> "$depfile" . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0 aqualung-0.9beta11/install-sh0000755000175000001440000001273610612341736013132 00000000000000#!/bin/sh # # install - install a program, script, or datafile # This comes from X11R5 (mit/util/scripts/install.sh). # # Copyright 1991 by the Massachusetts Institute of Technology # # Permission to use, copy, modify, distribute, and sell this software and its # documentation for any purpose is hereby granted without fee, provided that # the above copyright notice appear in all copies and that both that # copyright notice and this permission notice appear in supporting # documentation, and that the name of M.I.T. not be used in advertising or # publicity pertaining to distribution of the software without specific, # written prior permission. M.I.T. makes no representations about the # suitability of this software for any purpose. It is provided "as is" # without express or implied warranty. # # 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. It can only install one file at a time, a restriction # shared with many OS's install programs. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" transformbasename="" transform_arg="" instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 else true fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d $dst ]; then instcmd=: chmodcmd="" else instcmd=mkdir fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f $src -o -d $src ] then true else echo "install: $src does not exist" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 else true fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` else true fi fi ## this sed command emulates the dirname command dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-${defaultIFS}}" oIFS="${IFS}" # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` IFS="${oIFS}" pathcomp='' while [ $# -ne 0 ] ; do pathcomp="${pathcomp}${1}" shift if [ ! -d "${pathcomp}" ] ; then $mkdirprog "${pathcomp}" else true fi pathcomp="${pathcomp}/" done fi if [ x"$dir_arg" != x ] then $doit $instcmd $dst && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename $dst` else dstfile=`basename $dst $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename $dst` else true fi # Make a temp file name in the proper directory. dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp && trap "rm -f ${dsttmp}" 0 && # 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 $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && # Now rename the file to the real destination. $doit $rmcmd -f $dstdir/$dstfile && $doit $mvcmd $dsttmp $dstdir/$dstfile fi && exit 0 aqualung-0.9beta11/missing0000755000175000001440000002123110612341736012513 00000000000000#! /bin/sh # Common stub for a few missing GNU programs while installing. # Copyright 1996, 1997, 1999, 2000 Free Software Foundation, Inc. # Originally by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # 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. if test $# -eq 0; then echo 1>&2 "Try \`$0 --help' for more information" exit 1 fi run=: # In the cases where this matters, `missing' is being run in the # srcdir already. if test -f configure.ac; then configure_ac=configure.ac else configure_ac=configure.in fi case "$1" in --run) # Try to run requested program, and just exit if it succeeds. run= shift "$@" && exit 0 ;; esac # If it does not exist, or fails to run (possibly an outdated version), # try to emulate it. case "$1" in -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an error status if there is no known handling for PROGRAM. Options: -h, --help display this help and exit -v, --version output version information and exit --run try to run the given command, and emulate it if it fails Supported PROGRAM values: aclocal touch file \`aclocal.m4' autoconf touch file \`configure' autoheader touch file \`config.h.in' automake touch all \`Makefile.in' files bison create \`y.tab.[ch]', if possible, from existing .[ch] flex create \`lex.yy.c', if possible, from existing .c help2man touch the output file lex create \`lex.yy.c', if possible, from existing .c makeinfo touch the output file tar try tar, gnutar, gtar, then tar without non-portable flags yacc create \`y.tab.[ch]', if possible, from existing .[ch]" ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing 0.3 - GNU automake" ;; -*) echo 1>&2 "$0: Unknown \`$1' option" echo 1>&2 "Try \`$0 --help' for more information" exit 1 ;; aclocal) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." touch aclocal.m4 ;; autoconf) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." touch configure ;; autoheader) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`acconfig.h' or \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` test -z "$files" && files="config.h" touch_files= for f in $files; do case "$f" in *:*) touch_files="$touch_files "`echo "$f" | sed -e 's/^[^:]*://' -e 's/:.*//'`;; *) touch_files="$touch_files $f.in";; esac done touch $touch_files ;; automake) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." find . -type f -name Makefile.am -print | sed 's/\.am$/.in/' | while read f; do touch "$f"; done ;; bison|yacc) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.y' file. You may need the \`Bison' package in order for those modifications to take effect. You can get \`Bison' from any GNU archive site." rm -f y.tab.c y.tab.h if [ $# -ne 1 ]; then eval LASTARG="\${$#}" case "$LASTARG" in *.y) SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" y.tab.c fi SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" y.tab.h fi ;; esac fi if [ ! -f y.tab.h ]; then echo >y.tab.h fi if [ ! -f y.tab.c ]; then echo 'main() { return 0; }' >y.tab.c fi ;; lex|flex) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.l' file. You may need the \`Flex' package in order for those modifications to take effect. You can get \`Flex' from any GNU archive site." rm -f lex.yy.c if [ $# -ne 1 ]; then eval LASTARG="\${$#}" case "$LASTARG" in *.l) SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" lex.yy.c fi ;; esac fi if [ ! -f lex.yy.c ]; then echo 'main() { return 0; }' >lex.yy.c fi ;; help2man) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a dependency of a manual page. You may need the \`Help2man' package in order for those modifications to take effect. You can get \`Help2man' from any GNU archive site." file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` if test -z "$file"; then file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` fi if [ -f "$file" ]; then touch $file else test -z "$file" || exec >$file echo ".ab help2man is required to generate this page" exit 1 fi ;; makeinfo) if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then # We have makeinfo, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.texi' or \`.texinfo' file, or any other file indirectly affecting the aspect of the manual. The spurious call might also be the consequence of using a buggy \`make' (AIX, DU, IRIX). You might want to install the \`Texinfo' package or the \`GNU make' package. Grab either from any GNU archive site." file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` if test -z "$file"; then file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` fi touch $file ;; tar) shift if test -n "$run"; then echo 1>&2 "ERROR: \`tar' requires --run" exit 1 fi # We have already tried tar in the generic part. # Look for gnutar/gtar before invocation to avoid ugly error # messages. if (gnutar --version > /dev/null 2>&1); then gnutar ${1+"$@"} && exit 0 fi if (gtar --version > /dev/null 2>&1); then gtar ${1+"$@"} && exit 0 fi firstarg="$1" if shift; then case "$firstarg" in *o*) firstarg=`echo "$firstarg" | sed s/o//` tar "$firstarg" ${1+"$@"} && exit 0 ;; esac case "$firstarg" in *h*) firstarg=`echo "$firstarg" | sed s/h//` tar "$firstarg" ${1+"$@"} && exit 0 ;; esac fi echo 1>&2 "\ WARNING: I can't seem to be able to run \`tar' with the given arguments. You may want to install GNU tar or Free paxutils, or check the command line arguments." exit 1 ;; *) echo 1>&2 "\ WARNING: \`$1' is needed, and you do not seem to have it handy on your system. You might have modified some files without having the proper tools for further handling them. Check the \`README' file, it often tells you about the needed prerequirements for installing this package. You may also peek at any GNU archive site, in case some other package would contain this missing \`$1' program." exit 1 ;; esac exit 0 aqualung-0.9beta11/mkinstalldirs0000755000175000001440000000132010612341736013717 00000000000000#! /bin/sh # mkinstalldirs --- make directory hierarchy # Author: Noah Friedman # Created: 1993-05-16 # Public domain # $Id: mkinstalldirs 3 2004-09-03 15:10:42Z tszilagyi $ errstatus=0 for file do set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` shift pathcomp= for d do pathcomp="$pathcomp$d" case "$pathcomp" in -* ) pathcomp=./$pathcomp ;; esac if test ! -d "$pathcomp"; then echo "mkdir $pathcomp" mkdir "$pathcomp" || lasterr=$? if test ! -d "$pathcomp"; then errstatus=$lasterr fi fi pathcomp="$pathcomp/" done done exit $errstatus # mkinstalldirs ends here aqualung-0.9beta11/autogen.sh0000755000175000001440000000140711324131225013107 00000000000000#!/bin/sh echo " checking basic compilation tools ... " for tool in pkg-config aclocal autoheader autoconf automake gettext msgfmt do echo -n "$tool ... " if which $tool >/dev/null 2>&1 ; then echo "found." else echo "not found. *** You do not have $tool correctly installed. You cannot build aqualung without this tool." exit 1 fi done echo for tool in aclocal autoheader autoconf "automake --add-missing" do echo -n "running $tool ... " if $tool; then echo "done." else echo "failed. *** $tool returned an error." exit 1 fi done echo " You can now run: ./configure make make install Please take the time to subscribe to the project mailing list at: http://lists.sourceforge.net/lists/listinfo/aqualung-friends " aqualung-0.9beta11/ladspa.h0000644000175000001440000006571110612341736012544 00000000000000/* ladspa.h Linux Audio Developer's Simple Plugin API Version 1.1[LGPL]. Copyright (C) 2000-2002 Richard W.E. Furse, Paul Barton-Davis, Stefan Westerfeld. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ #ifndef LADSPA_INCLUDED #define LADSPA_INCLUDED #define LADSPA_VERSION "1.1" #define LADSPA_VERSION_MAJOR 1 #define LADSPA_VERSION_MINOR 1 #ifdef __cplusplus extern "C" { #endif /*****************************************************************************/ /* Overview: There is a large number of synthesis packages in use or development on the Linux platform at this time. This API (`The Linux Audio Developer's Simple Plugin API') attempts to give programmers the ability to write simple `plugin' audio processors in C/C++ and link them dynamically (`plug') into a range of these packages (`hosts'). It should be possible for any host and any plugin to communicate completely through this interface. This API is deliberately short and simple. To achieve compatibility with a range of promising Linux sound synthesis packages it attempts to find the `greatest common divisor' in their logical behaviour. Having said this, certain limiting decisions are implicit, notably the use of a fixed type (LADSPA_Data) for all data transfer and absence of a parameterised `initialisation' phase. See below for the LADSPA_Data typedef. Plugins are expected to distinguish between control and audio data. Plugins have `ports' that are inputs or outputs for audio or control data and each plugin is `run' for a `block' corresponding to a short time interval measured in samples. Audio data is communicated using arrays of LADSPA_Data, allowing a block of audio to be processed by the plugin in a single pass. Control data is communicated using single LADSPA_Data values. Control data has a single value at the start of a call to the `run()' or `run_adding()' function, and may be considered to remain this value for its duration. The plugin may assume that all its input and output ports have been connected to the relevant data location (see the `connect_port()' function below) before it is asked to run. Plugins will reside in shared object files suitable for dynamic linking by dlopen() and family. The file will provide a number of `plugin types' that can be used to instantiate actual plugins (sometimes known as `plugin instances') that can be connected together to perform tasks. This API contains very limited error-handling. */ /*****************************************************************************/ /* Fundamental data type passed in and out of plugin. This data type is used to communicate audio samples and control values. It is assumed that the plugin will work sensibly given any numeric input value although it may have a preferred range (see hints below). For audio it is generally assumed that 1.0f is the `0dB' reference amplitude and is a `normal' signal level. */ typedef float LADSPA_Data; /*****************************************************************************/ /* Special Plugin Properties: Optional features of the plugin type are encapsulated in the LADSPA_Properties type. This is assembled by ORing individual properties together. */ typedef int LADSPA_Properties; /* Property LADSPA_PROPERTY_REALTIME indicates that the plugin has a real-time dependency (e.g. listens to a MIDI device) and so its output must not be cached or subject to significant latency. */ #define LADSPA_PROPERTY_REALTIME 0x1 /* Property LADSPA_PROPERTY_INPLACE_BROKEN indicates that the plugin may cease to work correctly if the host elects to use the same data location for both input and output (see connect_port()). This should be avoided as enabling this flag makes it impossible for hosts to use the plugin to process audio `in-place.' */ #define LADSPA_PROPERTY_INPLACE_BROKEN 0x2 /* Property LADSPA_PROPERTY_HARD_RT_CAPABLE indicates that the plugin is capable of running not only in a conventional host but also in a `hard real-time' environment. To qualify for this the plugin must satisfy all of the following: (1) The plugin must not use malloc(), free() or other heap memory management within its run() or run_adding() functions. All new memory used in run() must be managed via the stack. These restrictions only apply to the run() function. (2) The plugin will not attempt to make use of any library functions with the exceptions of functions in the ANSI standard C and C maths libraries, which the host is expected to provide. (3) The plugin will not access files, devices, pipes, sockets, IPC or any other mechanism that might result in process or thread blocking. (4) The plugin will take an amount of time to execute a run() or run_adding() call approximately of form (A+B*SampleCount) where A and B depend on the machine and host in use. This amount of time may not depend on input signals or plugin state. The host is left the responsibility to perform timings to estimate upper bounds for A and B. */ #define LADSPA_PROPERTY_HARD_RT_CAPABLE 0x4 #define LADSPA_IS_REALTIME(x) ((x) & LADSPA_PROPERTY_REALTIME) #define LADSPA_IS_INPLACE_BROKEN(x) ((x) & LADSPA_PROPERTY_INPLACE_BROKEN) #define LADSPA_IS_HARD_RT_CAPABLE(x) ((x) & LADSPA_PROPERTY_HARD_RT_CAPABLE) /*****************************************************************************/ /* Plugin Ports: Plugins have `ports' that are inputs or outputs for audio or data. Ports can communicate arrays of LADSPA_Data (for audio inputs/outputs) or single LADSPA_Data values (for control input/outputs). This information is encapsulated in the LADSPA_PortDescriptor type which is assembled by ORing individual properties together. Note that a port must be an input or an output port but not both and that a port must be a control or audio port but not both. */ typedef int LADSPA_PortDescriptor; /* Property LADSPA_PORT_INPUT indicates that the port is an input. */ #define LADSPA_PORT_INPUT 0x1 /* Property LADSPA_PORT_OUTPUT indicates that the port is an output. */ #define LADSPA_PORT_OUTPUT 0x2 /* Property LADSPA_PORT_CONTROL indicates that the port is a control port. */ #define LADSPA_PORT_CONTROL 0x4 /* Property LADSPA_PORT_AUDIO indicates that the port is a audio port. */ #define LADSPA_PORT_AUDIO 0x8 #define LADSPA_IS_PORT_INPUT(x) ((x) & LADSPA_PORT_INPUT) #define LADSPA_IS_PORT_OUTPUT(x) ((x) & LADSPA_PORT_OUTPUT) #define LADSPA_IS_PORT_CONTROL(x) ((x) & LADSPA_PORT_CONTROL) #define LADSPA_IS_PORT_AUDIO(x) ((x) & LADSPA_PORT_AUDIO) /*****************************************************************************/ /* Plugin Port Range Hints: The host may wish to provide a representation of data entering or leaving a plugin (e.g. to generate a GUI automatically). To make this more meaningful, the plugin should provide `hints' to the host describing the usual values taken by the data. Note that these are only hints. The host may ignore them and the plugin must not assume that data supplied to it is meaningful. If the plugin receives invalid input data it is expected to continue to run without failure and, where possible, produce a sensible output (e.g. a high-pass filter given a negative cutoff frequency might switch to an all-pass mode). Hints are meaningful for all input and output ports but hints for input control ports are expected to be particularly useful. More hint information is encapsulated in the LADSPA_PortRangeHintDescriptor type which is assembled by ORing individual hint types together. Hints may require further LowerBound and UpperBound information. All the hint information for a particular port is aggregated in the LADSPA_PortRangeHint structure. */ typedef int LADSPA_PortRangeHintDescriptor; /* Hint LADSPA_HINT_BOUNDED_BELOW indicates that the LowerBound field of the LADSPA_PortRangeHint should be considered meaningful. The value in this field should be considered the (inclusive) lower bound of the valid range. If LADSPA_HINT_SAMPLE_RATE is also specified then the value of LowerBound should be multiplied by the sample rate. */ #define LADSPA_HINT_BOUNDED_BELOW 0x1 /* Hint LADSPA_HINT_BOUNDED_ABOVE indicates that the UpperBound field of the LADSPA_PortRangeHint should be considered meaningful. The value in this field should be considered the (inclusive) upper bound of the valid range. If LADSPA_HINT_SAMPLE_RATE is also specified then the value of UpperBound should be multiplied by the sample rate. */ #define LADSPA_HINT_BOUNDED_ABOVE 0x2 /* Hint LADSPA_HINT_TOGGLED indicates that the data item should be considered a Boolean toggle. Data less than or equal to zero should be considered `off' or `false,' and data above zero should be considered `on' or `true.' LADSPA_HINT_TOGGLED may not be used in conjunction with any other hint except LADSPA_HINT_DEFAULT_0 or LADSPA_HINT_DEFAULT_1. */ #define LADSPA_HINT_TOGGLED 0x4 /* Hint LADSPA_HINT_SAMPLE_RATE indicates that any bounds specified should be interpreted as multiples of the sample rate. For instance, a frequency range from 0Hz to the Nyquist frequency (half the sample rate) could be requested by this hint in conjunction with LowerBound = 0 and UpperBound = 0.5. Hosts that support bounds at all must support this hint to retain meaning. */ #define LADSPA_HINT_SAMPLE_RATE 0x8 /* Hint LADSPA_HINT_LOGARITHMIC indicates that it is likely that the user will find it more intuitive to view values using a logarithmic scale. This is particularly useful for frequencies and gains. */ #define LADSPA_HINT_LOGARITHMIC 0x10 /* Hint LADSPA_HINT_INTEGER indicates that a user interface would probably wish to provide a stepped control taking only integer values. Any bounds set should be slightly wider than the actual integer range required to avoid floating point rounding errors. For instance, the integer set {0,1,2,3} might be described as [-0.1, 3.1]. */ #define LADSPA_HINT_INTEGER 0x20 /* The various LADSPA_HINT_HAS_DEFAULT_* hints indicate a `normal' value for the port that is sensible as a default. For instance, this value is suitable for use as an initial value in a user interface or as a value the host might assign to a control port when the user has not provided one. Defaults are encoded using a mask so only one default may be specified for a port. Some of the hints make use of lower and upper bounds, in which case the relevant bound or bounds must be available and LADSPA_HINT_SAMPLE_RATE must be applied as usual. The resulting default must be rounded if LADSPA_HINT_INTEGER is present. Default values were introduced in LADSPA v1.1. */ #define LADSPA_HINT_DEFAULT_MASK 0x3C0 /* This default values indicates that no default is provided. */ #define LADSPA_HINT_DEFAULT_NONE 0x0 /* This default hint indicates that the suggested lower bound for the port should be used. */ #define LADSPA_HINT_DEFAULT_MINIMUM 0x40 /* This default hint indicates that a low value between the suggested lower and upper bounds should be chosen. For ports with LADSPA_HINT_LOGARITHMIC, this should be exp(log(lower) * 0.75 + log(upper) * 0.25). Otherwise, this should be (lower * 0.75 + upper * 0.25). */ #define LADSPA_HINT_DEFAULT_LOW 0x80 /* This default hint indicates that a middle value between the suggested lower and upper bounds should be chosen. For ports with LADSPA_HINT_LOGARITHMIC, this should be exp(log(lower) * 0.5 + log(upper) * 0.5). Otherwise, this should be (lower * 0.5 + upper * 0.5). */ #define LADSPA_HINT_DEFAULT_MIDDLE 0xC0 /* This default hint indicates that a high value between the suggested lower and upper bounds should be chosen. For ports with LADSPA_HINT_LOGARITHMIC, this should be exp(log(lower) * 0.25 + log(upper) * 0.75). Otherwise, this should be (lower * 0.25 + upper * 0.75). */ #define LADSPA_HINT_DEFAULT_HIGH 0x100 /* This default hint indicates that the suggested upper bound for the port should be used. */ #define LADSPA_HINT_DEFAULT_MAXIMUM 0x140 /* This default hint indicates that the number 0 should be used. Note that this default may be used in conjunction with LADSPA_HINT_TOGGLED. */ #define LADSPA_HINT_DEFAULT_0 0x200 /* This default hint indicates that the number 1 should be used. Note that this default may be used in conjunction with LADSPA_HINT_TOGGLED. */ #define LADSPA_HINT_DEFAULT_1 0x240 /* This default hint indicates that the number 100 should be used. */ #define LADSPA_HINT_DEFAULT_100 0x280 /* This default hint indicates that the Hz frequency of `concert A' should be used. This will be 440 unless the host uses an unusual tuning convention, in which case it may be within a few Hz. */ #define LADSPA_HINT_DEFAULT_440 0x2C0 #define LADSPA_IS_HINT_BOUNDED_BELOW(x) ((x) & LADSPA_HINT_BOUNDED_BELOW) #define LADSPA_IS_HINT_BOUNDED_ABOVE(x) ((x) & LADSPA_HINT_BOUNDED_ABOVE) #define LADSPA_IS_HINT_TOGGLED(x) ((x) & LADSPA_HINT_TOGGLED) #define LADSPA_IS_HINT_SAMPLE_RATE(x) ((x) & LADSPA_HINT_SAMPLE_RATE) #define LADSPA_IS_HINT_LOGARITHMIC(x) ((x) & LADSPA_HINT_LOGARITHMIC) #define LADSPA_IS_HINT_INTEGER(x) ((x) & LADSPA_HINT_INTEGER) #define LADSPA_IS_HINT_HAS_DEFAULT(x) ((x) & LADSPA_HINT_DEFAULT_MASK) #define LADSPA_IS_HINT_DEFAULT_MINIMUM(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \ == LADSPA_HINT_DEFAULT_MINIMUM) #define LADSPA_IS_HINT_DEFAULT_LOW(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \ == LADSPA_HINT_DEFAULT_LOW) #define LADSPA_IS_HINT_DEFAULT_MIDDLE(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \ == LADSPA_HINT_DEFAULT_MIDDLE) #define LADSPA_IS_HINT_DEFAULT_HIGH(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \ == LADSPA_HINT_DEFAULT_HIGH) #define LADSPA_IS_HINT_DEFAULT_MAXIMUM(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \ == LADSPA_HINT_DEFAULT_MAXIMUM) #define LADSPA_IS_HINT_DEFAULT_0(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \ == LADSPA_HINT_DEFAULT_0) #define LADSPA_IS_HINT_DEFAULT_1(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \ == LADSPA_HINT_DEFAULT_1) #define LADSPA_IS_HINT_DEFAULT_100(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \ == LADSPA_HINT_DEFAULT_100) #define LADSPA_IS_HINT_DEFAULT_440(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \ == LADSPA_HINT_DEFAULT_440) typedef struct _LADSPA_PortRangeHint { /* Hints about the port. */ LADSPA_PortRangeHintDescriptor HintDescriptor; /* Meaningful when hint LADSPA_HINT_BOUNDED_BELOW is active. When LADSPA_HINT_SAMPLE_RATE is also active then this value should be multiplied by the relevant sample rate. */ LADSPA_Data LowerBound; /* Meaningful when hint LADSPA_HINT_BOUNDED_ABOVE is active. When LADSPA_HINT_SAMPLE_RATE is also active then this value should be multiplied by the relevant sample rate. */ LADSPA_Data UpperBound; } LADSPA_PortRangeHint; /*****************************************************************************/ /* Plugin Handles: This plugin handle indicates a particular instance of the plugin concerned. It is valid to compare this to NULL (0 for C++) but otherwise the host should not attempt to interpret it. The plugin may use it to reference internal instance data. */ typedef void * LADSPA_Handle; /*****************************************************************************/ /* Descriptor for a Type of Plugin: This structure is used to describe a plugin type. It provides a number of functions to examine the type, instantiate it, link it to buffers and workspaces and to run it. */ typedef struct _LADSPA_Descriptor { /* This numeric identifier indicates the plugin type uniquely. Plugin programmers may reserve ranges of IDs from a central body to avoid clashes. Hosts may assume that IDs are below 0x1000000. */ unsigned long UniqueID; /* This identifier can be used as a unique, case-sensitive identifier for the plugin type within the plugin file. Plugin types should be identified by file and label rather than by index or plugin name, which may be changed in new plugin versions. Labels must not contain white-space characters. */ const char * Label; /* This indicates a number of properties of the plugin. */ LADSPA_Properties Properties; /* This member points to the null-terminated name of the plugin (e.g. "Sine Oscillator"). */ const char * Name; /* This member points to the null-terminated string indicating the maker of the plugin. This can be an empty string but not NULL. */ const char * Maker; /* This member points to the null-terminated string indicating any copyright applying to the plugin. If no Copyright applies the string "None" should be used. */ const char * Copyright; /* This indicates the number of ports (input AND output) present on the plugin. */ unsigned long PortCount; /* This member indicates an array of port descriptors. Valid indices vary from 0 to PortCount-1. */ const LADSPA_PortDescriptor * PortDescriptors; /* This member indicates an array of null-terminated strings describing ports (e.g. "Frequency (Hz)"). Valid indices vary from 0 to PortCount-1. */ const char * const * PortNames; /* This member indicates an array of range hints for each port (see above). Valid indices vary from 0 to PortCount-1. */ const LADSPA_PortRangeHint * PortRangeHints; /* This may be used by the plugin developer to pass any custom implementation data into an instantiate call. It must not be used or interpreted by the host. It is expected that most plugin writers will not use this facility as LADSPA_Handle should be used to hold instance data. */ void * ImplementationData; /* This member is a function pointer that instantiates a plugin. A handle is returned indicating the new plugin instance. The instantiation function accepts a sample rate as a parameter. The plugin descriptor from which this instantiate function was found must also be passed. This function must return NULL if instantiation fails. Note that instance initialisation should generally occur in activate() rather than here. */ LADSPA_Handle (*instantiate)(const struct _LADSPA_Descriptor * Descriptor, unsigned long SampleRate); /* This member is a function pointer that connects a port on an instantiated plugin to a memory location at which a block of data for the port will be read/written. The data location is expected to be an array of LADSPA_Data for audio ports or a single LADSPA_Data value for control ports. Memory issues will be managed by the host. The plugin must read/write the data at these locations every time run() or run_adding() is called and the data present at the time of this connection call should not be considered meaningful. connect_port() may be called more than once for a plugin instance to allow the host to change the buffers that the plugin is reading or writing. These calls may be made before or after activate() or deactivate() calls. connect_port() must be called at least once for each port before run() or run_adding() is called. When working with blocks of LADSPA_Data the plugin should pay careful attention to the block size passed to the run function as the block allocated may only just be large enough to contain the block of samples. Plugin writers should be aware that the host may elect to use the same buffer for more than one port and even use the same buffer for both input and output (see LADSPA_PROPERTY_INPLACE_BROKEN). However, overlapped buffers or use of a single buffer for both audio and control data may result in unexpected behaviour. */ void (*connect_port)(LADSPA_Handle Instance, unsigned long Port, LADSPA_Data * DataLocation); /* This member is a function pointer that initialises a plugin instance and activates it for use. This is separated from instantiate() to aid real-time support and so that hosts can reinitialise a plugin instance by calling deactivate() and then activate(). In this case the plugin instance must reset all state information dependent on the history of the plugin instance except for any data locations provided by connect_port() and any gain set by set_run_adding_gain(). If there is nothing for activate() to do then the plugin writer may provide a NULL rather than an empty function. When present, hosts must call this function once before run() (or run_adding()) is called for the first time. This call should be made as close to the run() call as possible and indicates to real-time plugins that they are now live. Plugins should not rely on a prompt call to run() after activate(). activate() may not be called again unless deactivate() is called first. Note that connect_port() may be called before or after a call to activate(). */ void (*activate)(LADSPA_Handle Instance); /* This method is a function pointer that runs an instance of a plugin for a block. Two parameters are required: the first is a handle to the particular instance to be run and the second indicates the block size (in samples) for which the plugin instance may run. Note that if an activate() function exists then it must be called before run() or run_adding(). If deactivate() is called for a plugin instance then the plugin instance may not be reused until activate() has been called again. If the plugin has the property LADSPA_PROPERTY_HARD_RT_CAPABLE then there are various things that the plugin should not do within the run() or run_adding() functions (see above). */ void (*run)(LADSPA_Handle Instance, unsigned long SampleCount); /* This method is a function pointer that runs an instance of a plugin for a block. This has identical behaviour to run() except in the way data is output from the plugin. When run() is used, values are written directly to the memory areas associated with the output ports. However when run_adding() is called, values must be added to the values already present in the memory areas. Furthermore, output values written must be scaled by the current gain set by set_run_adding_gain() (see below) before addition. run_adding() is optional. When it is not provided by a plugin, this function pointer must be set to NULL. When it is provided, the function set_run_adding_gain() must be provided also. */ void (*run_adding)(LADSPA_Handle Instance, unsigned long SampleCount); /* This method is a function pointer that sets the output gain for use when run_adding() is called (see above). If this function is never called the gain is assumed to default to 1. Gain information should be retained when activate() or deactivate() are called. This function should be provided by the plugin if and only if the run_adding() function is provided. When it is absent this function pointer must be set to NULL. */ void (*set_run_adding_gain)(LADSPA_Handle Instance, LADSPA_Data Gain); /* This is the counterpart to activate() (see above). If there is nothing for deactivate() to do then the plugin writer may provide a NULL rather than an empty function. Hosts must deactivate all activated units after they have been run() (or run_adding()) for the last time. This call should be made as close to the last run() call as possible and indicates to real-time plugins that they are no longer live. Plugins should not rely on prompt deactivation. Note that connect_port() may be called before or after a call to deactivate(). Deactivation is not similar to pausing as the plugin instance will be reinitialised when activate() is called to reuse it. */ void (*deactivate)(LADSPA_Handle Instance); /* Once an instance of a plugin has been finished with it can be deleted using the following function. The instance handle passed ceases to be valid after this call. If activate() was called for a plugin instance then a corresponding call to deactivate() must be made before cleanup() is called. */ void (*cleanup)(LADSPA_Handle Instance); } LADSPA_Descriptor; /**********************************************************************/ /* Accessing a Plugin: */ /* The exact mechanism by which plugins are loaded is host-dependent, however all most hosts will need to know is the name of shared object file containing the plugin types. To allow multiple hosts to share plugin types, hosts may wish to check for environment variable LADSPA_PATH. If present, this should contain a colon-separated path indicating directories that should be searched (in order) when loading plugin types. A plugin programmer must include a function called "ladspa_descriptor" with the following function prototype within the shared object file. This function will have C-style linkage (if you are using C++ this is taken care of by the `extern "C"' clause at the top of the file). A host will find the plugin shared object file by one means or another, find the ladspa_descriptor() function, call it, and proceed from there. Plugin types are accessed by index (not ID) using values from 0 upwards. Out of range indexes must result in this function returning NULL, so the plugin count can be determined by checking for the least index that results in NULL being returned. */ const LADSPA_Descriptor * ladspa_descriptor(unsigned long Index); /* Datatype corresponding to the ladspa_descriptor() function. */ typedef const LADSPA_Descriptor * (*LADSPA_Descriptor_Function)(unsigned long Index); /**********************************************************************/ #ifdef __cplusplus } #endif #endif /* LADSPA_INCLUDED */ /* EOF */ aqualung-0.9beta11/doc/0000777000175000001440000000000011331334362011742 500000000000000aqualung-0.9beta11/doc/README0000644000175000001440000000115211107574203012536 00000000000000The Aqualung documentation is maintained in XML conforming to a custom DTD created exclusively for this program. Other formats like HTML and PDF and manual page are generated by applying XSL Stylesheets. The latest version of the User's Manual is available for downloading or reading at the project homepage: http://aqualung.factorial.hu/docs.html The full documentation can be generated by running `make aqualung-doc'. The required tools are xsltproc (for all formats) and a decent LaTeX distribution such as tetex of texlive (only for PDF). The manual page is always accessible locally by typing `man aqualung'. aqualung-0.9beta11/doc/Makefile.am0000644000175000001440000000405711136163560013723 00000000000000man_MANS = aqualung.1 docdir = $(pkgdatadir)/doc doc_DATA = README split.sh aqualung-doc.css aqualung-doc.dtd aqualung-doc.xml *.xsl *.eps *.png EXTRA_DIST = $(man_MANS) $(doc_DATA) aqualung-doc: pdf html bz2 man txt pdf: aqualung-doc.pdf html: aqualung-doc.html index.html bz2: aqualung-doc-html.tar.bz2 aqualung-doc-html-chunk.tar.bz2 man: aqualung.1 txt: aqualung.1.txt aqualung-doc.pdf: aqualung-latex.xsl aqualung-doc.xml xsltproc aqualung-latex.xsl aqualung-doc.xml | sed -e 's/^[ \t]*@\?//' > aqualung-doc.tex while test `latex aqualung-doc.tex | grep 'Rerun' | wc -l` != 0 ; do : ; done dvipdf -sPAPERSIZE=a4 aqualung-doc.dvi aqualung-doc.html: aqualung-xhtml.xsl aqualung-doc.xml xsltproc --stringparam date "`LANG=C date -u`" aqualung-xhtml.xsl aqualung-doc.xml | sed -e 's/^[ \t]*@//' > aqualung-doc.html index.html: aqualung-xhtml-multipage.xsl aqualung-xhtml.xsl aqualung-doc.xml xsltproc --stringparam date "`LANG=C date -u`" aqualung-xhtml-multipage.xsl aqualung-doc.xml | sed -e 's/^[ \t]*@//' | ./split.sh aqualung-doc-html.tar.bz2: aqualung-doc.html mkdir aqualung-doc-html cp aqualung-doc.html aqualung-doc.css *.png aqualung-doc-html tar cvjf aqualung-doc-html.tar.bz2 aqualung-doc-html rm -r aqualung-doc-html aqualung-doc-html-chunk.tar.bz2: index.html mkdir aqualung-doc-html-chunk cp aqualung-doc-part_*.html index.html aqualung-doc.css *.png aqualung-doc-html-chunk tar cvjf aqualung-doc-html-chunk.tar.bz2 aqualung-doc-html-chunk rm -r aqualung-doc-html-chunk aqualung.1: aqualung-man.xsl aqualung-doc.xml xsltproc --stringparam date "`LANG=C date -u +'%d %B %Y'`" aqualung-man.xsl aqualung-doc.xml | sed 's/^[ \t]*@\?//' > aqualung.1 aqualung.1.txt: aqualung.1 man ./aqualung.1 | col -bx | sed 's/\$$ \+/\$$ /' > aqualung.1.txt .PHONY: clean clean-all clean: rm -f *.tex *.aux *.dvi *.log *.out *.toc clean-all: rm -f *.html *.tar.bz2 aqualung.1 aqualung.1.txt *.pdf upload: clean-all aqualung-doc clean @echo @ls @echo lftp -c 'set net:limit-rate 0:8000; open aqualung && cd manual && mirror -R -X .svn/ -X Makefile* -X *.sh' aqualung-0.9beta11/doc/Makefile.in0000644000175000001440000003150211331334252013722 00000000000000# Makefile.in generated by automake 1.10.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # This Makefile.in 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. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = doc DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = SOURCES = DIST_SOURCES = man1dir = $(mandir)/man1 am__installdirs = "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(docdir)" NROFF = nroff MANS = $(man_MANS) am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; docDATA_INSTALL = $(INSTALL_DATA) DATA = $(doc_DATA) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBAVCODEC_CFLAGS = @LIBAVCODEC_CFLAGS@ LIBAVCODEC_LIBS = @LIBAVCODEC_LIBS@ LIBAVFORMAT_CFLAGS = @LIBAVFORMAT_CFLAGS@ LIBAVFORMAT_LIBS = @LIBAVFORMAT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = $(pkgdatadir)/doc dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ var = @var@ man_MANS = aqualung.1 doc_DATA = README split.sh aqualung-doc.css aqualung-doc.dtd aqualung-doc.xml *.xsl *.eps *.png EXTRA_DIST = $(man_MANS) $(doc_DATA) all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu doc/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh install-man1: $(man1_MANS) $(man_MANS) @$(NORMAL_INSTALL) test -z "$(man1dir)" || $(MKDIR_P) "$(DESTDIR)$(man1dir)" @list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ for i in $$l2; do \ case "$$i" in \ *.1*) list="$$list $$i" ;; \ esac; \ done; \ for i in $$list; do \ if test -f $$i; then file=$$i; \ else file=$(srcdir)/$$i; fi; \ ext=`echo $$i | sed -e 's/^.*\\.//'`; \ case "$$ext" in \ 1*) ;; \ *) ext='1' ;; \ esac; \ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ inst=`echo $$inst | sed -e 's/^.*\///'`; \ inst=`echo $$inst | sed '$(transform)'`.$$ext; \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst"; \ done uninstall-man1: @$(NORMAL_UNINSTALL) @list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ for i in $$l2; do \ case "$$i" in \ *.1*) list="$$list $$i" ;; \ esac; \ done; \ for i in $$list; do \ ext=`echo $$i | sed -e 's/^.*\\.//'`; \ case "$$ext" in \ 1*) ;; \ *) ext='1' ;; \ esac; \ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ inst=`echo $$inst | sed -e 's/^.*\///'`; \ inst=`echo $$inst | sed '$(transform)'`.$$ext; \ echo " rm -f '$(DESTDIR)$(man1dir)/$$inst'"; \ rm -f "$(DESTDIR)$(man1dir)/$$inst"; \ done install-docDATA: $(doc_DATA) @$(NORMAL_INSTALL) test -z "$(docdir)" || $(MKDIR_P) "$(DESTDIR)$(docdir)" @list='$(doc_DATA)'; for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ f=$(am__strip_dir) \ echo " $(docDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(docdir)/$$f'"; \ $(docDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(docdir)/$$f"; \ done uninstall-docDATA: @$(NORMAL_UNINSTALL) @list='$(doc_DATA)'; for p in $$list; do \ f=$(am__strip_dir) \ echo " rm -f '$(DESTDIR)$(docdir)/$$f'"; \ rm -f "$(DESTDIR)$(docdir)/$$f"; \ done tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(MANS) $(DATA) installdirs: for dir in "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(docdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: info: info-am info-am: install-data-am: install-docDATA install-man install-dvi: install-dvi-am install-exec-am: install-html: install-html-am install-info: install-info-am install-man: install-man1 install-pdf: install-pdf-am install-ps: install-ps-am installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-docDATA uninstall-man uninstall-man: uninstall-man1 .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic distclean \ distclean-generic distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am \ install-docDATA install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-man1 install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am uninstall uninstall-am uninstall-docDATA \ uninstall-man uninstall-man1 aqualung-doc: pdf html bz2 man txt pdf: aqualung-doc.pdf html: aqualung-doc.html index.html bz2: aqualung-doc-html.tar.bz2 aqualung-doc-html-chunk.tar.bz2 man: aqualung.1 txt: aqualung.1.txt aqualung-doc.pdf: aqualung-latex.xsl aqualung-doc.xml xsltproc aqualung-latex.xsl aqualung-doc.xml | sed -e 's/^[ \t]*@\?//' > aqualung-doc.tex while test `latex aqualung-doc.tex | grep 'Rerun' | wc -l` != 0 ; do : ; done dvipdf -sPAPERSIZE=a4 aqualung-doc.dvi aqualung-doc.html: aqualung-xhtml.xsl aqualung-doc.xml xsltproc --stringparam date "`LANG=C date -u`" aqualung-xhtml.xsl aqualung-doc.xml | sed -e 's/^[ \t]*@//' > aqualung-doc.html index.html: aqualung-xhtml-multipage.xsl aqualung-xhtml.xsl aqualung-doc.xml xsltproc --stringparam date "`LANG=C date -u`" aqualung-xhtml-multipage.xsl aqualung-doc.xml | sed -e 's/^[ \t]*@//' | ./split.sh aqualung-doc-html.tar.bz2: aqualung-doc.html mkdir aqualung-doc-html cp aqualung-doc.html aqualung-doc.css *.png aqualung-doc-html tar cvjf aqualung-doc-html.tar.bz2 aqualung-doc-html rm -r aqualung-doc-html aqualung-doc-html-chunk.tar.bz2: index.html mkdir aqualung-doc-html-chunk cp aqualung-doc-part_*.html index.html aqualung-doc.css *.png aqualung-doc-html-chunk tar cvjf aqualung-doc-html-chunk.tar.bz2 aqualung-doc-html-chunk rm -r aqualung-doc-html-chunk aqualung.1: aqualung-man.xsl aqualung-doc.xml xsltproc --stringparam date "`LANG=C date -u +'%d %B %Y'`" aqualung-man.xsl aqualung-doc.xml | sed 's/^[ \t]*@\?//' > aqualung.1 aqualung.1.txt: aqualung.1 man ./aqualung.1 | col -bx | sed 's/\$$ \+/\$$ /' > aqualung.1.txt .PHONY: clean clean-all clean: rm -f *.tex *.aux *.dvi *.log *.out *.toc clean-all: rm -f *.html *.tar.bz2 aqualung.1 aqualung.1.txt *.pdf upload: clean-all aqualung-doc clean @echo @ls @echo lftp -c 'set net:limit-rate 0:8000; open aqualung && cd manual && mirror -R -X .svn/ -X Makefile* -X *.sh' # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: aqualung-0.9beta11/doc/aqualung.10000644000175000001440000002755211331325774013577 00000000000000.TH AQUALUNG 1 "23 January 2010" .SH NAME aqualung \- Music player for GNU/Linux .SH SYNOPSIS .TP aqualung --help .TP aqualung --version .TP aqualung [--output (jack|pulse|alsa|oss|sndio|win32)] [options] [file1 [file2 ...]] .SH DESCRIPTION .P Aqualung is an advanced music player originally targeted at the GNU/Linux operating system, today also running on FreeBSD, OpenBSD and Microsoft Windows. It plays audio CDs, internet radio streams and podcasts as well as soundfiles in just about any audio format and has the feature of inserting \fBno gaps\fR between adjacent tracks. It also supports high quality sample rate conversion between the file and the output device, when necessary. .P Audio CDs can be played back and ripped with on-the-fly conversion to WAV, FLAC, Ogg Vorbis or CBR/VBR MP3 (gapless via LAME). Seamless tagging of the created files is offered as part of the process. Internet radio stations streaming Ogg Vorbis or MP3 are supported. Subscribing to RSS and Atom audio podcasts is supported: Aqualung can automatically download and add new files to the Music Store. Optional limits for the age, size and number of downloaded files can be set. .P Almost all sample-based, uncompressed formats (e.g. WAV, AIFF, AU etc.), as well as files encoded with FLAC (the Free Lossless Audio Codec), Ogg Vorbis, Ogg Speex, MPEG Audio (including the infamous MP3 format), MOD audio formats (MOD, S3M, XM, IT, etc.), Musepack and Monkey's Audio Codec are supported. Numerous formats and codecs are also supported via the FFmpeg project, including AC3, AAC, WMA, WavPack and the soundtrack of many video formats. There is also a native (non-FFmpeg) WavPack decoder. The program can play the music through OSS, ALSA, sndio, PulseAudio, the JACK Audio Connection Kit, or even using the Win32 Sound API (available only under Cygwin or native Win32). Depending on the compile-time options, not all file formats and output drivers may be usable in a particular build. Type aqualung -v to get a list of all the compiled-in features. .P Aqualung supports the LADSPA 1.1 plugin standard. You can use any suitable plugin to enhance the music you are listening to. .P Other features of the program are: tabbed playlist, internally working volume and balance controls (not touching the soundcard mixer), multiple skin support, random seeking during playback, track repeat, list repeat and shuffle mode (besides normal playback). In track repeat mode the looping range is adjustable. Aqualung will come up in the same state as it was when you closed it, including playback modes, volume and balance settings, currently processing LADSPA plugins, window sizes, positions and visibility, and other miscellaneous options. Aqualung has the ability to display and edit Ogg Xiph comments, ID3v1, ID3v2 and APE tags, as well as FLAC picture frames found in files that support them. See the section about metadata support for full reference. .P The method of assembling the title string of a track is programmable (via a user-provided Lua function) and can include nearly any metadata item or audio file attribute. See the documentation of the \fBProgrammable title format file\fR config setting for full reference. .P You can control any running instance of the program remotely from the command line (start, stop, pause etc.). Remote loading or enqueueing soundfiles as well as complete playlists is also supported. .P In addition to all this, Aqualung provides a so-called Music Store that is an XML-based music database, capable of storing various metadata about music on your computer (including, but not limited to, the names of artists, and the titles of records and tracks). You can (and should) organize your music into trees of Artists/Records/Tracks, thereby making life easier than with the all-in-one Winamp/XMMS playlist. Importing file metadata (ID3v1, ID3v2 tags, Ogg Xiph comments, APE metadata) into the Music Store as well as getting track names from a CDDB/FreeDB database is supported. For audio CDs, CD-Text retrieval is also implemented. .P Please refer to the documentation available at the homepage for a detailed description of features, usage tips and troubleshooting issues. This manual page is merely an abstract from the User's Manual, and documents only the command line interface of the program for quick reference. .SH OPTIONS .P Normally you should be able to start Aqualung without any options. This case the output device will be selected by probing for a usable driver (in order of JACK, PulseAudio, ALSA, OSS) with default parameters. .P If no driver could be started with default parameters, or you want to explicitly choose a suitable output configuration, you have to tell the program which output device to use. This is possible with the -o (--output) option. There are specific optional parameters for all five output drivers. You can also specify which sample rate converter you want to use, or request a list of available converters. You may also control another instance of the program remotely, or add files to the Playlist. .TP .B General options .TP -D, --disk-realtime .br Try to use realtime (SCHED_FIFO) scheduling for disk thread, a background worker thread doing file decoding and sample rate conversion. Try this (and optionally -Y) if you experience short audio dropouts caused by other programs (e.g. web browser loading a complex page). .TP -Y, --disk-priority .br When running -D, set scheduler priority to (defaults to 1). .TP .B Options relevant to ALSA output .TP -d, --device .br Set the output device (defaults to 'default'). .TP -r, --rate .br Set the output sample rate. .TP -R, --realtime .br Try to use realtime (SCHED_FIFO) scheduling for ALSA output thread. .TP -P, --priority .br When running --realtime, set scheduler priority to (default is 1 when -R is used). .TP .B Options relevant to OSS output .TP -d, --device .br Set the output device (defaults to /dev/audio on OpenBSD, /dev/dsp on other Unices). .TP -r, --rate .br Set the output sample rate. .TP -R, --realtime .br Try to use realtime (SCHED_FIFO) scheduling for OSS output thread. .TP -P, --priority .br When running --realtime, set scheduler priority to (default is 1 when -R is used). .TP .B Options relevant to JACK output .TP -a[,], --auto[=,] .br Auto-connect output ports to given JACK ports (defaults to first two hardware playback ports). .TP -c, --client .br Set client name (needed if you want to run multiple instances of the program). .P Note that in the case when JACK output has been selected as part of the automatic output device detection, the -a option is implicitly applied. .TP .B Options relevant to PulseAudio and sndio output .TP -r, --rate .br Set the output sample rate. .TP -R, --realtime .br Try to use realtime (SCHED_FIFO) scheduling for sndio output thread. .TP -P, --priority .br When running --realtime, set scheduler priority to (default is 1 when -R is used). .TP .B Options relevant to Win32 output .TP -r, --rate .br Set the output sample rate. .TP .B Options relevant to the Sample Rate Converter .TP -s[], --srctype[=] .br Choose the SRC type, or print the list of available types if no number given. The default is SRC type 4 (Linear Interpolator). .TP .B Options for remote cue control .P Note that remote controlling of instances is only possible if the instance you want to send a command to is running as the same user as you are when you issue the remote command. .TP -N, --session .br Specify the instance number to send the remote command to. Instances are numbered on a per user basis, starting with 0. Except for the zero-th instance (started first), the instance number is displayed in the title bar of the main window (e.g.: `Aqualung.3'). If you don't use this option, the following options will control the zero-th instance by default, except for -L which defaults to the present instance (so as to be able to start playback immediately from the command line). .TP -B, --back .br Jump to previous track. .TP -F, --fwd .br Jump to next track. .TP -L, --play .br Start playing. .TP -U, --pause .br Pause playback, or resume if already paused. .TP -T, --stop .br Stop playback. .TP -V, --volume [m|M]|[=] .br Adjust the volume. m/M means mute; if = is present, the remote instance's volume control will be set to the value specified, otherwise, the volume will be adjusted by the supplied (signed) value. The values are in dB units. .TP -Q, --quit .br Terminate remote instance. .TP .B Options for file loading .P You may specify filenames on the command line. These may be ordinary soundfiles playable by Aqualung, directories, or playlist files you saved earlier. The program will decide if a file is a playlist, and add its contents accordingly. In addition to Aqualung's native (XML) playlist format, the program will load M3U and PLS playlists whenever possible. .P If you used the --session option (see above), the files will be sent to the Aqualung instance you specified. Otherwise a new instance will start up with the files you specified. Note that if you enabled the \fBSave and restore the Playlist on exit/startup\fR option in the \fBSettings\fR dialog, the files you specify will be loaded \fBafter\fR the automatically loaded ones. .TP -E, --enqueue .br Enqueue added files to the Playlist instead of loading them (which removes the previous contents of the Playlist). Use this if you want to keep the existing items in the Playlist. .TP -t[], --tab[=] .br Specify target tab for file loading (either remotely using the --session option, or at startup). If --tab is used without the name parameter, the files will be added to a new (untitled) tab. If a name is supplied, Aqualung will check whether a tab with that name already exists. If so, the files will be loaded (or enqueued if you used -E) to that tab. If no such tab exists, one with that name will be created, and the content goes there. .TP .B Options for changing state of Playlist/Music Store windows .TP -l [yes|no], --show-pl=[yes|no] .br Show/hide Playlist window. .TP -m [yes|no], --show-ms=[yes|no] .br Show/hide Music Store window. .TP .B Examples .TP $ aqualung -s3 -o alsa -R -r 48000 -d plughw:0,0 .TP $ aqualung --srctype=1 --output oss --rate 96000 .TP $ aqualung -o jack --auto=system:playback_17,system:playback_18 .TP $ aqualung -o jack -a -E --tab="Led Zeppelin" `find ./ledzeppelin/ -name \*.flac` .SH FILES .P Here is a list of files that Aqualung creates, reads and relies on. .TP ~/.aqualung .br Directory containing user settings. .TP ~/.aqualung/config.xml .br GUI (skin, window size/position, etc.) and other settings. .TP ~/.aqualung/plugin.xml .br List of running plugins and all their settings. .TP ~/.aqualung/playlist.xml .br Automatically saved and restored playlist (if you enable this feature). .TP ~/.aqualung/ .br Locally available skin (useful for skin development). .TP ${prefix}/share/aqualung/skin .br System-wide skin directory. .SH ENVIRONMENT .P Aqualung obeys two environment variables concerning LADSPA plugins. .TP LADSPA_PATH .br Colon-separated list of paths to search for LADSPA plugin .so files. .TP LADSPA_RDF_PATH .br Colon-separated list of paths to RDF metadata files about these plugins. .P When any of these is not specified, the program will use sensible defaults and look in the obvious places. .SH AUTHORS .br Tom Szilagyi .br Peter Szilagyi .br Tomasz Maka .br Jeremy Evans .SH BUGS .P Yes. Report them to our bugtracker at or write to our mailing list (the subscription interface is accessible from the project homepage). .SH HOMEPAGE .P Please go to to download the latest version, access the Aqualung bugtracker and subscribe to the mailing list. .SH USER'S MANUAL .P The latest version of the User's Manual is available at the project homepage. aqualung-0.9beta11/doc/split.sh0000755000175000001440000000042411107574203013351 00000000000000#!/bin/sh OUTPUT='/dev/null' while read line; do if [ "$line" = "&&" ] ; then read OUTPUT; echo '' >> $OUTPUT else echo "$line" >> $OUTPUT fi done aqualung-0.9beta11/doc/aqualung-doc.css0000644000175000001440000000154611136163560014761 00000000000000body { font-family: "Bitstream Vera Sans", sans-serif; } hr { color: #aaaaaa; background-color: #aaaaaa; border: 0px; height: 1px; } img { border: 0px; } table { margin-left: auto; margin-right: auto; } tt { font-family: "Bitstream Vera Sans Mono", monospace; } code { font-family: "Bitstream Vera Sans Mono", monospace; white-space: nowrap; } pre { font-family: "Bitstream Vera Sans Mono", monospace; border: 1px solid #ccccff; padding: 5px; margin-left: 20px; } p { text-align: justify; } a.external { background: url(external.png) center right no-repeat; padding-right: 13px; } img.screenshot { padding-left: 12px; padding-bottom: 6px; float: right; } .gui { font-style: italic; text-decoration: underline; white-space: nowrap; } .toc1 { margin-left: 50px; } .toc2 { margin-left: 100px; } .toc3 { margin-left: 150px; } aqualung-0.9beta11/doc/aqualung-doc.dtd0000644000175000001440000000426011331325774014744 00000000000000 aqualung-0.9beta11/doc/aqualung-doc.xml0000644000175000001440000042117011324145246014770 00000000000000 Aqualung User's Manual 2006-2010 Peter Szilagyi Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.2
or any later version published by the Free Software Foundation.

Aqualung is an advanced music player originally targeted at the GNU/Linux operating system, today also running on FreeBSD, OpenBSD and Microsoft Windows. It plays audio CDs, internet radio streams and podcasts as well as soundfiles in just about any audio format and has the feature of inserting no gaps between adjacent tracks. It also supports high quality sample rate conversion between the file and the output device, when necessary.

Audio CDs can be played back and ripped with on-the-fly conversion to WAV, FLAC, Ogg Vorbis or CBR/VBR MP3 (gapless via LAME). Seamless tagging of the created files is offered as part of the process. Internet radio stations streaming Ogg Vorbis or MP3 are supported. Subscribing to RSS and Atom audio podcasts is supported: Aqualung can automatically download and add new files to the Music Store. Optional limits for the age, size and number of downloaded files can be set.

Almost all sample-based, uncompressed formats (e.g. WAV, AIFF, AU etc.), as well as files encoded with FLAC (the Free Lossless Audio Codec), Ogg Vorbis, Ogg Speex, MPEG Audio (including the infamous MP3 format), MOD audio formats (MOD, S3M, XM, IT, etc.), Musepack and Monkey's Audio Codec are supported. Numerous formats and codecs are also supported via the FFmpeg project, including AC3, AAC, WMA, WavPack and the soundtrack of many video formats. There is also a native (non-FFmpeg) WavPack decoder. The program can play the music through OSS, ALSA, sndio, PulseAudio, the JACK Audio Connection Kit, or even using the Win32 Sound API (available only under Cygwin or native Win32). Depending on the compile-time options, not all file formats and output drivers may be usable in a particular build. Type aqualung -v to get a list of all the compiled-in features.

Aqualung supports the LADSPA 1.1 plugin standard. You can use any suitable plugin to enhance the music you are listening to.

Other features of the program are: tabbed playlist, internally working volume and balance controls (not touching the soundcard mixer), multiple skin support, random seeking during playback, track repeat, list repeat and shuffle mode (besides normal playback). In track repeat mode the looping range is adjustable. Aqualung will come up in the same state as it was when you closed it, including playback modes, volume and balance settings, currently processing LADSPA plugins, window sizes, positions and visibility, and other miscellaneous options. Aqualung has the ability to display and edit Ogg Xiph comments, ID3v1, ID3v2 and APE tags, as well as FLAC picture frames found in files that support them. See the section about metadata support for full reference.

The method of assembling the title string of a track is programmable (via a user-provided Lua function) and can include nearly any metadata item or audio file attribute. See the documentation of the Programmable title format file config setting for full reference.

You can control any running instance of the program remotely from the command line (start, stop, pause etc.). Remote loading or enqueueing soundfiles as well as complete playlists is also supported.

In addition to all this, Aqualung provides a so-called Music Store that is an XML-based music database, capable of storing various metadata about music on your computer (including, but not limited to, the names of artists, and the titles of records and tracks). You can (and should) organize your music into trees of Artists/Records/Tracks, thereby making life easier than with the all-in-one Winamp/XMMS playlist. Importing file metadata (ID3v1, ID3v2 tags, Ogg Xiph comments, APE metadata) into the Music Store as well as getting track names from a CDDB/FreeDB database is supported. For audio CDs, CD-Text retrieval is also implemented.

If you'd like to get your hands on the program quickly rather than to spend your evening reading the rest of the manual, here is the absolute minimum you need to know to successfully use the program. So make sure to read this (deliberately short) chapter, and come back for the rest when you have questions while using the program. Ultimately, you may ask questions on the aqualung-friends mailing list.

It is not hard to get Aqualung up and running on your machine, although for beginners the number of compile-time options might be intimidating at first. The steps you need to take depend on the platform and operating system you use. For detailed information please look at the relevant page of the Aqualung website.

In case you are not used to compiling software yourself, you may check whether there is a distribution-provided package of Aqualung. Installing such a package is generally the easiest and fastest way to get Aqualung, however this way you won't be able to try the latest features. Currently there are Aqualung packages for major Linux distributions such as Debian, Gentoo, SuSE, etc. as well as FreeBSD. If your distribution lacks such a package, consider contacting the organization maintaining the distribution and ask them to provide a package of Aqualung. Anyway, you might have to compile Aqualung from source. This is not very hard, either the configure script tries to adapt Aqualung to your system as much as possible without breaking the program. See the above website for more information.

On Microsoft Windows, all you have to do is download and run the self-extracting installer utility, which guides you through a few easy to follow steps and installs the program on your machine. Make sure to visit this page for more information about the Windows version of Aqualung.

Aqualung has a large number of configuration settings, which are adjustable through the user interface at run-time (no need to edit config files by hand), and are remembered across multiple invocations of the program. When Aqualung starts for the first time, it creates a configuration based on some wired-in defaults. A good way of exploring the program's capabilities is poking through the configuration area. You can access this by clicking in the main window with the right mouse button, which will pop up the program's main menu. Choosing Settings from the menu will open the configuration dialog.

In fact, clicking with the right mouse button almost anywhere is a generally smart idea. Aqualung has lots of context-sensitive popup menus in the Music Store, the Playlist (often embedded in the main window) and elsewhere. It's good to keep this in mind when taking the explorative approach instead of reading the whole manual right away.

Let's add some music to the Playlist and start playback right away. Right-click the Add files button, and choose Add directory from the menu. (The right-clicking trick works for the other two buttons as well. Left-clicking is a shortcut to immediately execute the action denoted by the button's caption.) Choose a directory with some music under it. It's OK to have subdirectories under this directory, the program will search for playable files recursively. After the Playlist starts to get populated with tracks, press play, or double-click on one of the tracks to play. Press i to see metadata information about the selected track.

Now that you have some music playing, let's get more organized. In the Music Store window click in the empty area with the right mouse button and choose Create empty store... from the menu. Enter a meaningful name such as Tom's Music and choose a location to save the XML file of the store to. This should be a writable location, so it is wise to stick to a location inside your home directory. (A system-wide path or a remote NFS mount with read-only access won't do.)

You can have any number of such stores in the Music Store organizer, and it is indeed a great idea to have separate stores for music differentiated by origin, genre, or some other aspect. One great use is multiple stores with the actual music files stored on multiple remote machines, one store for each machine. Or just a store for your local music and another for files on your bedroom file server box. There are several possibilities.

But how do you populate the store with music you already have on your drive? It's easy if your music is stored in an organized manner on the filesystem level. As a minimum, this means that tracks intended to go into one store are found under a common root directory in the filesystem (there may be several directory layers down from the root to the individual files, but there must be a common ancestor). In this case the so-called Music Store Builder will take care of things for you. Right-click on your newly-created empty store and choose Build / Update store from filesystem. Choose Independent mode and in the dialog you get, enter the root directory under which your collection resides. As you can probably guess at this point, the store builder interface is pretty flexible, however the default settings should be good to get something together quickly without further hassle.

Pressing OK will start the process, during which the directory structure below the root you specified will be traversed. The artist/record/track names are determined from potentially multiple data sources (CDDB, metadata e.g. ID3v2 tags or Ogg Xiph comments, and filesystem names). The logic involved is fairly elaborate. You are strongly advised to read the detailed usage instructions for the Music Store Builder.

You can play CDs with Aqualung easily. Just put the CD in one of your CD drives, and if everything goes well, Aqualung will detect it, do a CDDB lookup to retrieve artist, record and track info (CD-Text is also used if the CD has it), and make it available to you through the special Music Store node called CD Audio.

You don't have to be happy with what you have so far. The Music Store paradigm is fairly addictive, as it's much easier to drop something into the Playlist from the Music Store than physically placing a CD in the drive. So as you keep expanding your CD collection, you will probably want to have those records in one of your music stores, too. In this case all you have to do is choose Rip CD... from the disc's popup menu, and supply some information. We won't go into details here (please refer to this section in case the interface is not obvious). However, it is worth stating that you should have a separate directory for the files of each record. Ripping multiple CDs into the same directory won't work.

aqualung --help
Print help message with valid parameters and example invocations.
aqualung --version
Print version information and list of compiled-in features.
aqualung [--output (jack|pulse|alsa|oss|sndio|win32)] [options] [file1 [file2 ...]]

Normally you should be able to start Aqualung without any options. This case the output device will be selected by probing for a usable driver (in order of JACK, PulseAudio, ALSA, OSS) with default parameters.

If no driver could be started with default parameters, or you want to explicitly choose a suitable output configuration, you have to tell the program which output device to use. This is possible with the -o (--output) option. There are specific optional parameters for all five output drivers. You can also specify which sample rate converter you want to use, or request a list of available converters. You may also control another instance of the program remotely, or add files to the Playlist.

-D, --disk-realtime
Try to use realtime (SCHED_FIFO) scheduling for disk thread, a background worker thread doing file decoding and sample rate conversion. Try this (and optionally -Y) if you experience short audio dropouts caused by other programs (e.g. web browser loading a complex page).
-Y, --disk-priority <int>
When running -D, set scheduler priority to <int> (defaults to 1).
-d, --device <name>
Set the output device (defaults to 'default').
-r, --rate <int>
Set the output sample rate.
-R, --realtime
Try to use realtime (SCHED_FIFO) scheduling for ALSA output thread.
-P, --priority <int>
When running --realtime, set scheduler priority to <int> (default is 1 when -R is used).
-d, --device <name>
Set the output device (defaults to /dev/audio on OpenBSD, /dev/dsp on other Unices).
-r, --rate <int>
Set the output sample rate.
-R, --realtime
Try to use realtime (SCHED_FIFO) scheduling for OSS output thread.
-P, --priority <int>
When running --realtime, set scheduler priority to <int> (default is 1 when -R is used).
-a[<port_L>,<port_R>], --auto[=<port_L>,<port_R>]
Auto-connect output ports to given JACK ports (defaults to first two hardware playback ports).
-c, --client <name>
Set client name (needed if you want to run multiple instances of the program).

Note that in the case when JACK output has been selected as part of the automatic output device detection, the -a option is implicitly applied.

-r, --rate <int>
Set the output sample rate.
-R, --realtime
Try to use realtime (SCHED_FIFO) scheduling for sndio output thread.
-P, --priority <int>
When running --realtime, set scheduler priority to <int> (default is 1 when -R is used).
-r, --rate <int>
Set the output sample rate.
-s[<int>], --srctype[=<int>]
Choose the SRC type, or print the list of available types if no number given. The default is SRC type 4 (Linear Interpolator).

Note that remote controlling of instances is only possible if the instance you want to send a command to is running as the same user as you are when you issue the remote command.

-N, --session <int>
Specify the instance number to send the remote command to. Instances are numbered on a per user basis, starting with 0. Except for the zero-th instance (started first), the instance number is displayed in the title bar of the main window (e.g.: Aqualung.3). If you don't use this option, the following options will control the zero-th instance by default, except for -L which defaults to the present instance (so as to be able to start playback immediately from the command line).
-B, --back
Jump to previous track.
-F, --fwd
Jump to next track.
-L, --play
Start playing.
-U, --pause
Pause playback, or resume if already paused.
-T, --stop
Stop playback.
-V, --volume [m|M]|[=]<val>
Adjust the volume. m/M means mute; if = is present, the remote instance's volume control will be set to the value specified, otherwise, the volume will be adjusted by the supplied (signed) value. The values are in dB units.
-Q, --quit
Terminate remote instance.

You may specify filenames on the command line. These may be ordinary soundfiles playable by Aqualung, directories, or playlist files you saved earlier. The program will decide if a file is a playlist, and add its contents accordingly. In addition to Aqualung's native (XML) playlist format, the program will load M3U and PLS playlists whenever possible.

If you used the --session option (see above), the files will be sent to the Aqualung instance you specified. Otherwise a new instance will start up with the files you specified. Note that if you enabled the Save and restore the Playlist on exit/startup option in the Settings dialog, the files you specify will be loaded after the automatically loaded ones.

-E, --enqueue
Enqueue added files to the Playlist instead of loading them (which removes the previous contents of the Playlist). Use this if you want to keep the existing items in the Playlist.
-t[<name>], --tab[=<name>]
Specify target tab for file loading (either remotely using the --session option, or at startup). If --tab is used without the name parameter, the files will be added to a new (untitled) tab. If a name is supplied, Aqualung will check whether a tab with that name already exists. If so, the files will be loaded (or enqueued if you used -E) to that tab. If no such tab exists, one with that name will be created, and the content goes there.

It is possible to set up a host program such as a browser, file manager etc. to use Aqualung for opening soundfiles. To do this, a command line with the following properties should be used:

  • if an Aqualung instance is already running, send the file(s) to that instance;
  • if no instance is running, start up a new instance;
  • either case, start playing the file(s) immediately after loading them.

One solution to this is to use

aqualung -N0 -E -L -t'File Manager' %s

where %s is one or more filenames. It should be noted that the file associations (the mechanism of knowing which files to open via Aqualung) is completely within the scope of the host program.

-l [yes|no], --show-pl=[yes|no]
Show/hide Playlist window.
-m [yes|no], --show-ms=[yes|no]
Show/hide Music Store window.
$ aqualung -s3 -o alsa -R -r 48000 -d plughw:0,0
$ aqualung --srctype=1 --output oss --rate 96000
$ aqualung -o jack --auto=system:playback_17,system:playback_18
$ aqualung -o jack -a -E --tab="Led Zeppelin" `find ./ledzeppelin/ -name \*.flac`

Aqualung obeys two environment variables concerning LADSPA plugins.

LADSPA_PATH
Colon-separated list of paths to search for LADSPA plugin .so files.
LADSPA_RDF_PATH
Colon-separated list of paths to RDF metadata files about these plugins.

When any of these is not specified, the program will use sensible defaults and look in the obvious places.

Here is a list of files that Aqualung creates, reads and relies on.

~/.aqualung
Directory containing user settings.
~/.aqualung/config.xml
GUI (skin, window size/position, etc.) and other settings.
~/.aqualung/plugin.xml
List of running plugins and all their settings.
~/.aqualung/playlist.xml
Automatically saved and restored playlist (if you enable this feature).
~/.aqualung/<skin-name>
Locally available skin <skin-name> (useful for skin development).
${prefix}/share/aqualung/skin
System-wide skin directory.

You can control most of the program from this window. The cue controls in the bottom-left corner are fairly obvious. You can drag the large slider in the middle for seeking. There are two smaller sliders above that, the left one is for adjusting the volume and the right one for adjusting the balance. Above these, there are two horizontal text areas showing information about the currently playing track, and input/output parameters such as sample rate, mono/stereo, bitrate, output driver (e.g. OSS, ALSA, JACK) etc. The first trick to learn is that these lines are horizontally draggable with the mouse if the text does not fit in the available visible space. However, they don't scroll automatically, and for a very good reason.

In the upper left corner, you find one bigger and two smaller displays that show track times: elapsed time, remaining time and total track time. The big display also shows the current volume and balance setting when appropriate. By clicking in these displays, you can rearrange the displays as you want them. The following figure shows how the displays switch their contents after clicking into them with the left (L) or right (R) mouse button.

time displays reacting to mouse clicks

In the bottom right corner there are additional buttons. The buttons with the letters display or hide additional windows of the program:

FX Ladspa Patch Builder
MS Music Store
PL Playlist

Note that depending on the skin, these buttons may come with images instead of the letters above. However, their functionality does not change.

The remaining three buttons are to select the playback mode. When none of these buttons is depressed, playback goes the normal way. The buttons are mutually exclusive, and select track repeat, list repeat or shuffle mode. I'm sure you can figure out which is which. If you select track repeat, a loop bar appears above the seek bar, with two markers. The markers can be dragged to select the looping range. When they are at the left and right end positions, the whole song is repeated. The looping range can also be selected using keyboard shortcuts. When track repeat is enabled and the current song is playing (or paused), < will set the start of the looping range to the current playing position; > does the same for the end of the looping range.

Volume and balance slider tricks:

  • Shift + any mouse button sets the volume and balance sliders back to 0 dB and Center position, respectively. This combination also works for the loop bar, in which case the looping range is set to the whole song.
  • Clicking and holding the right mouse button on these sliders shows their position in the big time display without altering the value.

An additional thing to know about the volume control is that it ranges up to +6 dB. This means you can send a bigger signal to the audio device than in the original file. With 0 dB corresponding to 100% signal level, +6 dB is almost exactly 200% signal level (and 4 times signal power as well). This means you can overdrive your output device, and since clipping will occur at 100% anyway, it will cause nasty digital distortion much worse than simple analog overdrive. If you have a track with a reasonably low level, you can go above 0 dB with the volume control. But today most CDs are mastered to keep the average volume level very close to the 0 dB (or 100%) top, and so they will likely distort with as little as +1 dB additional gain. The moral is: if you want it loud, turn up your external amp. You can also consider using RVA if the volume level of your tracks tends to vary in a wide range see this section for details.

On a related note, another thing to watch out for is LADSPA plugins (in case you use them). It is very common that the signal level leaving a plugin is greater than the signal level the plugin gets on its input. So it is best to leave a few dB of headroom if you do that. A very typical case is boosting some frequency bands a few dB with an EQ plugin. You should decrease the overall volume level with as much dB as the largest boost (or even more), or you are risking that the signal will get chopped causing bad distortion. Alternatively, apply this limiter plugin as the last one in the processing chain, but only if you know what you are doing.

Right-clicking almost anywhere in the window will bring up a menu that allows access to the Settings dialog, the Skin Chooser, the JACK Port Setup dialog (present only when running the program with JACK output), and the About box. The latter may be useful to see which features have been compiled into the program. (If you haven't read the page about compiling yet: the configuration of the program can be adapted so as not to require certain libraries when compiling, and not provide certain features accordingly.)

The Playlist normally receives its contents from the Music Store. However, you can put any file in the Playlist regardless of the contents of your Music Store, using the Add files button at the bottom of the window. Adding a directory or a URL are also supported, by right-clicking on the button and selecting the appropriate menu item, Add directory or Add URL.

The Add URL menu item can be used to listen to Internet radio stations streaming Ogg Vorbis or MP3. You will be shown a dialog with an entry, in which you should enter the URL of the stream. Pressing OK will add it to the Playlist. After you start playing the stream, the Playlist entry changes to the name of the radio station, with the description provided by the station in brackets.

The other two buttons (Select all, Remove selected) function as you would expect them when clicked with the left mouse button. Clicking with the right mouse button brings up popup menus that contain further options as seen with the Add files button.

There is a statusbar under the list showing the total time of the Playlist and the duration of the selected tracks, as well as the size of the songs (if enabled).

The Playlist can not only maintain a linear list of songs, but is also capable of keeping the tracks of albums together. This is done when a Store, Artist or Record has been added to the Playlist using the so-called Album mode, available from the popup menu in Music Store. If you tend to use it extensively, there is an option on the Settings / Playlist page to make it default, so drag & drop and adding via keyboard shortcut will use this mode automatically.

Aqualung supports playlist tabs, which allow you to have multiple playlists for your music at the same time, very similarly to multiple tabbed browsing in Firefox. Creating new tabs is possible via CTRL+T in the Playlist window, double-clicking on the tab bar, or using the right-click context menu of the tab labels. This context menu can also be used to rename tabs, close other tabs, or undo closing. Another trick is that middle clicking on an item in the Music Store adds the content to a new playlist tab, which will be named after the middle-clicked element by default. Closing a tab has several ways: clicking the close button located on each tab, middle-clicking on a tab, using the tab context menu, or by pressing CTRL+W in the Playlist window. Undo close tab is possible until you quit Aqualung. Tabs can be reordered via drag & drop.

The contents of the Playlist can be saved and restored automatically when the program exits and starts up, and/or periodically with adjustable interval. (Whether this should be done is a configuration option, covered later.) In addition to this, you can save the Playlist manually at any time, or load a previously saved playlist file. To do this, right-click in the Playlist area, which will bring up a popup menu with these features.

The Playlist is saved as an XML file, unless you specify a filename ending in .m3u, in which case it is saved in M3U format (one filename per line). When saving an XML playlist, you should normally end your filename with .xml however, this is only good practice and not necessary. If you choose Save all playlists, the XML will be a multi-tabbed playlist, containing all tabs, while Save playlist saves the current playlist only. When saving all playlists, it will always use the XML format, as the M3U file format does not support multiple playlists. Note that the XML playlist file format is not compatible with Winamp/XMMS .m3u files. However, Aqualung will open playlists in M3U and PLS formats whenever possible.

When opening a multi-tabbed playlist, all opened tabs will be appended after the present ones, and the existing tabs will be remained intact, regardless of whether you chose loading (which normally clears the current playlist before adding) or enqueueing (which appends songs to the playlist). Opening any other playlist type (single XML playlist created by Save playlist, M3U or PLS playlists) will behave according to the option you chose (Load in new tab, Load or Enqueue).

The usual cut, copy and paste functions are accessible via keyboard shortcuts, and work across playlist tabs as well. Rearranging tracks by drag & dropping items is also supported. You can even drag a track from a playlist into another, by dragging on the tab first in order to switch to the target playlist. The only restriction is that album nodes cannot be pasted or dropped inside another album node.

The Music Store is a simple database of all your music. The central philosophy of this program is that you have a large storage (ideally an entire hard drive or a separate partition) to store all your music files. This is not necessary for the program to work. The audio files can be scattered around your system as long as you have read permissions to them. However, it is strongly recommended that you devote a separate directory for all the music (for example, /music would be a convenient place to store files that are owned by root, but readable by all users). Moreover, you can maintain several collections on different machines this way, and share them with other users via NFS, while keeping a (probably smaller) collection on your local hard drive.

In these central directories, create subdirectories for each artist you have CDs from. The directory names do not have to contain the exact names, you can for example create /music/ledzep for Led Zeppelin, /music/crimson for King Crimson, /music/hendrix for Jimi Hendrix and so on. In these directories, create subdirectories for each CD you have. Once again, the directory names for the records do not need to fully contain the record titles; they can be short and without spaces and special characters.

Into the directories of records, you should rip the CD using the built-in ripper of Aqualung, tagging the files and adding the record to the Music Store as part of the process. See this section for details.

Aqualung comes with a Music Store Builder facility, which allows you to easily create a store from your existing audio files. This is essential if you already have a large music collection on your harddrive. Please make sure to read this section to understand the concepts and usage of this feature.

Each store, artist, record and track has fields you can fill in via bringing up the Edit dialog for that item. The Visible name is obviously the string that will appear in the Music Store tree, and in the Playlist. The Name to sort by is a string key used for sorting items on the same level of hierarchy (all artists, records of a given artist, and tracks of a given record).

For artists, you should enter the same here as the Visible name for ordinary band names (you can use copy & paste to do that, or simply press ENTER while the cursor is in the visible name entry). However, for some artists you will enter a slightly modified string: Mayall, John or just Mayall for John Mayall, for example. This is to ensure that John Mayall (which is the visible name) appears between Mahavishnu and Morphine, and not somewhere near Jethro Tull.

Records have a Year field to store the release year. The Name to sort by field should usually be this year, but you can use explicit numbering or whatever you like as well. If multiple records of an artist have the same year (double albums, multi-CD collections, or just multiple studio albums published in the same year), you may use e.g. 1969-1, 1969-2, etc. to keep them in proper order.

As for tracks, a two-digit, zero-padded decimal numbering would be excellent for the sort key. If you added tracks to the records using the aforementioned Auto-create tracks from these files feature of the Record add dialog, the tracks will be automatically numbered for you this way.

Last but not least, every item has a Comment field that may contain multiple lines of text, and is perfectly optional to use for any store, artist, record or track. When you have entered something in this field, it will be displayed in the lower area of the Music Store window when the corresponding item is selected in the tree. Use this to store miscellaneous data, such as birth dates of artists, or comments like Recorded live at Royal Albert Hall, ... or Digitized from original LP for records, and movement subtitles for tracks that have them.

As mentioned before, you may maintain several collections of audio files on several machines. Each collection is arranged in an artist/record/track hierarchy, and appears under a store item in the Music Store tree. The metadata describing one collection is located in one file on your filesystem.

On the Settings / Music Store page you can specify several database files whose content is intended to appear in your Music Store. If a given file is unavailable, the corresponding store item will be missing from the Music Store. If the file is readonly, you can play the music, but you won't be allowed to change (add, edit, remove, etc.) the items in the store. Finally, if you have write permission on the file, you will be allowed to change the items.

The order in which the stores appear in the Music Store is the order of the corresponding database files in the list. The list can be reordered via drag & drop.

The program can read and write all sorts of metadata (normally referred to as tags in everyday speech) embedded in the audio files themselves. To see such metadata for a particular track, you will utilize the File info dialog accessible from the Music Store (right-click popup menus for Tracks, or press i) and the Playlist (right-click popup menu for Playlist entries, or press i).

When you open the File info dialog from the Music Store, you will find buttons to the right of every metadata field that was read from the file (unless the store is readonly). By pressing these buttons, the associated data will be imported into the corresponding field of the relevant Track. For metadata fields that don't have a corresponding field in the Music Store, you can append their contents to the Comment field as a catch-all solution.

Please make sure to check out the comprehensive guide to Aqualung's metadata capabilities.

Aqualung supports retrieving matches from a CDDB database, as well as submitting new records or updating existing ones. The features are available by right-clicking on a record in the Music Store and choosing the appropriate menu item.

The CDDB query option starts a query (which can last a bit long if there are a lot of matches), and displays a dialog with the search results. It tends to work even if you have already encoded your audio files in a lossy format.

If there are multiple matches, you can select any of them using the combo box at the top of the dialog. The displayed fields are all editable, which is useful in case you find no fully acceptable match, but want to use one that is almost perfect. The track names can be edited by double-clicking on the desired track, or single clicking on an already selected entry.

By pressing the OK button the track names of the currently selected lookup results will be propagated into the Music Store. The artist name, record title and year are not automatically set, but can be imported using the Import as Artist, Import as Title and Import as Year buttons on the right. Record title and year can also be imported as sort keys, after you once pressed the corresponding import button. Other data (category, genre and extended data) can be appended to the comment field of the record in question using the Add to Comments button next to the appropriate text entry.

The CDDB submission option brings up a dialog which contains the artist, title, year, category, genre and extended data fields, and the track list. All fields (including track names) are editable. The artist, title, year and category fields are mandatory, the genre and extended data are optional. Track names should be all set as well. You are also recommended to comply with the naming rules when submitting new records.

If Aqualung was compiled with Audio CD support, a store called CD Audio appears as the first store in Music Store. This special store contains a node for each drive in your machine. Detecting hot-swappable devices such as external USB drives is supported, so you don't need to restart the program after plugging in your drive. Aqualung will notice not only the change of discs in devices, but device changes themselves, too.

When you insert a CD in a drive, the corresponding node will contain the audio tracks on that disc. The artist, record and track names are automatically set from CD-Text information if found on the CD, or a CDDB lookup.

The drive nodes have options available from the popup menu for adding content to the Playlist, manual CDDB lookup and submission just like normal album nodes do. They have some further CD specific options as well.

The most important feature is ripping the CD. Choosing Rip CD... from the popup menu will bring up a dialog with several options broken into notebook pages. The Source page is for selecting the tracks to be ripped, and specifying the artist, record and track names. If the CDDB lookup was successful, these fields are initialized appropriately. On the Output page you can select the directory where to put the audio files, and optionally the music store to which you would like to add the ripped CD. The destination directory must be empty; it is best to create a fresh new directory each time you rip a CD. Only music stores with write permission are offered, so you might not see all of them. The desired file/encoding format can also be selected, along with settings concerning quality, such as compression level or bitrate. The supported destination formats are WAV, FLAC, Ogg Vorbis and MP3. There is also an option to set whether the files should be tagged with metadata. (WAV does not have a tagging mechanism. Other formats are tagged according to their native tagging mechanism.)

CD Ripping always happens with maximum available speed and with error correction modes manually set before every run on the last page titled Paranoia. Here you can basically choose between safe and slow ripping, and faster, but more insecure operation. The latter might be useful if you know by experience that your equipment is reliable, and the CD you are about to rip is not scratched or dirty. Even so, it is probably a good idea to use the available extra error protection unless you are really in a hurry.

It is possible to display information about the inserted disc (CD-Text), or the drive itself (general info, reading or writing capabilities, etc.). The tray can also be ejected, if the driver supports this operation. Note that ripping and playing a CD at the same time is impossible for obvious reasons.

If Aqualung is compiled with podcast support, you will have a store called Podcasts in your Music Store. All feeds you are subscribed to will show up as nodes under this store. Subscriptions can be made using the Subscribe to new feed right-click menu of the Podcasts store.

When you subscribe to a feed, you need to enter the URL of the feed and a directory where to put the downloaded files. Supported feed formats are all versions of RSS and Atom.

Aqualung can automatically check for updates and download new files. The check interval can be specified in hours, with a 0.25 hour resolution. The automatic update facility can be disabled for a feed by unchecking the checkbutton before the name of this option.

There are three different limits that you can apply on a per feed basis. All of them are optional, and can be turned on/off with their respective checkbutton.

  • Maximum number of items: the number of downloaded files will never exceed this. If necessary, Aqualung will delete older files to meet this requirement.
  • Remove older items: Aqualung will automatically remove files that are older than the given number of days. If a feed offers files for download that are older than this limit, they won't even be downloaded. Note that if a feed incorrectly specifies the date of the items, it may happen that no files are downloaded due to this limit if so, turn it off, and update again.
  • Maximum space to use: the downloaded files will not occupy more space than specified by this option.

If some files need to be deleted due to limit constraints, the oldest one will be removed first to keep fresh material available as long as possible. Once you have subscribed to a feed, you can edit the check interval and limit settings using the Edit feed menu item.

New feeds are appended to the Podcasts store. They can be reordered later using the Reorder feeds menu item of the Podcasts store.

There is a check menu item called Automatically update feeds in the Podcasts store popup menu to globally enable/disable automatic feed updates for all feeds. If unchecked, the Edit Feed dialog will show a note about this option being disabled instead of the feed's own check interval.

When a feed is being updated, its title is changed to indicate how many new files are to be downloaded, and shows the completion ratio as well. You can abort an update process by clicking the Abort ongoing update right-click menu item of the feed in question, which is naturally available only during updates.

If you use JACK output, you need this dialog to route the outputs of the program somewhere (most likely to the playback ports representing the soundcard driver). If you want the outputs to be connected automatically to the first two hardware playback devices, use the -a (or --auto) command line option.

On the left, each output port has a list of its current connections. By clicking on any list item, that connection will be removed. The Clear connections button removes all connections from the output ports.

The notebook on the right has a page for all client programs and hardware devices available to the JACK server. Naturally only those are shown which are data sinks (hardware playback devices or inputs of JACK clients), thus connectable to outputs which are data sources. By selecting a notebook page, you will see a list of that client's input ports. Clicking on a list item connects the port to the currently selected Aqualung output port (which has a blue header). You can change the selected output port by clicking on the unselected (grey) list header. When you add connections to the output ports, the selection alters between the two outputs so connecting both outputs is very fast and easy.

If you start up another JACK client while the dialog is open, you may press the Rescan button to make it appear in the notebook. Closing and re-opening the dialog has the same effect, since JACK ports are re-read and a new dialog instance is built every time.

This dialog lets you choose from the available skins at any time. All officially supported skins are shipped with Aqualung, and installed in the system-wide skin directory during make install. Skins placed in the local skin directory will only be locally available, which is useful for developing new skins or experimenting with the existing ones. If there are skins in the system-wide directory and the local directory having the same name, the local one takes precedence.

When compiled with Systray support, Aqualung will place its icon in the system tray (notification area), and lets all of its windows be closed while still playing music. In this mode pressing the upper right X on the main window will not exit the program, only hide its windows.

Clicking on the systray icon with the left mouse button will toggle visibility of the program's windows. Clicking with the right button will bring up a popup menu allowing showing/hiding the windows, basic cueing, and quitting Aqualung.

The systray icon has a tooltip displaying the same text as the main window's title. So it's easy to see what track is currently playing, and also the Aqualung instance ID (in case of more instances).

It is possible to export files from the Music Store or Playlist to external formats. This is especially handy if you own a portable music player, since it can be easily filled with music you already have on your computer, transcoding and tagging the files so they can be readily used by the device. The feature is available from the right-click popup menus (both in Music Store and Playlist), and via the shortcut x or X (in Music Store only). It operates on the selected Music Store node, or the selected tracks in the Playlist.

The export dialog handles the settings of output directory, filename and file format. Subdirectories can be created for artists and/or records, with adjustable limit for the length of the created directory names. The actual filename is generated using the filename template. This template is very similar to the well-known Title format in Settings / General, only it accepts three more special sequences: %n for the track number (two digit, zero padded), %i for an identifier which is unique within an export session, and %x for the file extension. The latter is determined by the output file format, and will be one of flac, ogg, mp3 or wav.

The file format setting is exactly the same as with CD ripping, refer to this section for details.

The metadata of the exported files is transcoded to the new format as well as the audio data; read more about this here.

One great feature of the program is that you can apply LADSPA plugins to the music. You can use the equalizer of your choice instead of a built-in one, along with other plugins. You can process your sound with Aqualung in ways that the author of this program never thought of. A recommended set is TAP-plugins.

Of course, faithful reproduction of music does not require or permit pervasive signal processing, since that is not the purpose of such activity. However, the technology is at your disposal and it's up to you to use or misuse it. It may be necessary to adapt your listening gear to the acoustic environment, using small amounts of equalization preferably in a subtractive manner. In addition to this, I also like to spice my tracks with a small amount of tubewarmth to feel that warm tube sound even with my transistor amplifiers, and to bring out even the finest details of the music.

The plugin chain you build is automatically saved and restored, so once you get it right for your listening environment, you should rarely need to touch it.

Some tricks concerning the LADSPA patch builder:

  • Multiple plugins can be selected from the available plugins list and added at once by clicking on the Add button or pressing a or A.
  • A single plugin can be added immediately by double-clicking it in the available plugins list.
  • Plugins in the running list can be (un)bypassed with the middle mouse button.
  • The configuration window of the running plugins can be brought up by double-clicking on them (same as clicking on the Configure button).
  • If a plugin is selected in the running plugins list, pressing DELETE will remove it (same as pressing the Remove button).
  • Running plugins can be rearranged at any time (changing the order in which they are processed) via dragging them with the mouse.
  • In the configuration windows of plugins, setting input controls back to their default value is possible by shift-clicking on the slider. This does not work for toggled or integer inputs (those that don't have a slider displayed for them).

RVA stands for Relative Volume Adjustment, and refers to a system that is supposed to compensate for the fact that the perceived volume levels of tracks from different records are sometimes quite different. With usual players, you are left with the possibility to adjust the volume manually, when necessary; but not with Aqualung.

Besides having a fully-fledged system for RVA, Aqualung also supports using already existing ReplayGain or RVA information present in your audio files' metadata. If you are interested in this, read on, but make sure to also check out this section.

You have to do two things prior to using RVA in Aqualung. First, you have to calculate the volume of the tracks you want affected by the RVA system. To do this, use the Calculate volume option in the Music Store found in the right-click popup menus of Stores, Artists, Records and Tracks. When you activate this option, a small window will pop up with a progress bar. You can move this window out of your way, and proceed with using Aqualung. Processing will be carried out in the background, and should not affect your ability to play music at all. Calculated volume levels will be saved and restored with the rest of the Music Store. The values are shown in the Edit track dialog.

When you are done with this, open the Settings dialog (right-click almost anywhere in the main window), and select the Playback RVA notebook page.

If Enable playback RVA is unchecked, the whole RVA system is turned off. No tracks receive adjustment. If playback RVA is enabled, you can select a listening environment that matches your setup. The idea is that the better your environment, the smaller adjustment you need to enjoy the music. If you work in a noisy workshop (and listen to Aqualung-played music) then it is best to minimize the volume differences between tracks so all tracks will be uniformly audible at a particular volume setting. If you can afford to listen to music in a silent room with high quality headphones or good near-field monitors, you should choose Audiophile which will yield no change to volumes.

The diagram shows the input/output transfer function applied to the previously measured track loudness to obtain the adjustment needed for a particular track. The diagram is 24 dB large in both directions, with the (0, 0) point being in the upper right corner. The blue line shows the identity function (no change), while the red line shows the output volume (the actual transfer function). The adjustment applied at a particular track volume is the vertical distance between the two lines at that position. The transfer function is linear. You can use the Reference volume and Steepness controls to change its position.

In most cases, it is desirable that tracks of the same record receive the same adjustment, so as to preserve the volume differences internal to the record. This can be enabled by checking Apply averaged RVA to tracks of the same record. When enabled, volume levels of the same record will be averaged and all tracks will be adjusted by an average value. Please note that measured volume levels are converted to RVA values when you add something from the Music Store to the Playlist. Therefore, this feature works only when you add an Artist or a Record. If you add a record by adding all the Tracks manually one after another, they will all receive independent RVA values. Also, changing RVA settings will not affect entries already in the Playlist.

There are many records having one or two tracks that really stand out of the average volume level. (For example, there is one very silent track on an otherwise loud record.) In this case, these tracks would pull down the average volume. To get around this, you can adjust a threshold that will be used to sort out tracks that stand out too much and will be disregarded when computing the average volume.

You can select whether you want to specify a threshold in linear volume units [dBFS] or you want to specify a percentage of the standard deviation of the set of individual track volumes to use as a threshold. The default values should work well for the vast majority of records. If you always want every track's volume to count in the average adjustment of the record, choose the linear threshold and set it to a really big value (say, 30 dB) so all tracks will be within this range.

For external tracks added to the Playlist and having no volume information, you can specify a fixed RVA value using RVA for Unmeasured Files. This applies to all tracks coming from outside the Music Store or a native XML playlist file, and to URLs.

You also have the possibility to always use a manually specified, fixed value as RVA for a particular track. In the Edit track dialog for that track, check the Use manual RVA value checkbox and set the value with the spinbutton on its right. If you e.g. import an ID3v2.4 RVA tag from an MP3 file, it will also set this field thereby circumventing Aqualung's own RVA calculation.

It is possible to have more volume calculations in progress at a time. If you need to measure a few records, you don't have to wait for the previous one to finish. RVA calculations can also be paused, so should you suddenly need the whole CPU capacity, you don't have to abort the process just pause it, and resume when things go down.

Aqualung's Music Store Builder allows you to easily create a store from your existing audio files. This is essential if you already have a large music collection on your harddrive.

The Builder supports two approaches for automatically adding audio files to the Music Store. The directory driven mode requires the collection to be organized in a strict filesystem structure, where the directory structure itself specifies which files belong to a record, and which records belong to an artist. The structure should conform to one of the following patterns:

a) root / record / track b) root / artist / record / track c) root / artist / artist / record / track d) root / artist / artist / artist / record / track

Pattern a) is useful when you do not have separate subdirectories for artists, only for records. The b) means that each artist and record has its own subdirectory. It corresponds to the structure introduced above along with the Music Store. The patterns c) and d) are for those who have too many artists to keep them at the same level; you may thus have a subdirectory for every artist starting with letter a, b, etc., or you can even dedicate two levels to them, perhaps as b/be/beatles, c/cr/crimson, etc.

The independent mode does not follow any directory structure, only searches for audio files recursively starting from root. This doesn't allow the Builder to perform CDDB lookups, so only metadata and filename transformations are available with this mode. If your audio files are basically organized in a directory structure that allows a directory driven build to be performed, but you also happen to have audio files on higher (record or artist) levels, run the Builder in directory driven mode first, then use the independent mode on the same root directory to add the outstanding files too.

The Builder can gain information about your music from three sources: metadata (if your audio files are correctly tagged), CDDB lookups, and the filesystem names of the audio files and directories themselves.

If you are up to building a new store, first create an empty store (right-click in Music Store, then choose the Create empty store item), then right-click on the new store and choose Build / Update store from filesystem. After selecting the desired building mode, the builder dialog appears with several options broken down into five notebook pages. Later, if you only want to update the content of a store, you can start a build process on a non-empty store as well.

On the General page you have to select the root directory of your music collection. With the directory driven mode, the appropriate structure should also be selected.

You can exclude files from the build process that match a wildcard pattern (or more precisely, at least one element in a list of wildcard patterns). The list is comma-separated, e.g. *.jpg,*.png,*.gif will cause all files having jpg, png, or gif extension to be left out. Note that hidden files (whose name starts with a period) are always excluded. Also note that no spaces should be used around the commas, because they would be counted in the wildcard patterns, causing a lot of headache.

Similarly, you may include only those files that match a wildcard pattern. The syntax is the same as with the exclusion. This easily allows you to build a store containing music e.g. encoded with FLAC, and another store for Ogg, while the audio files can be placed together even in the same directory. Exclude and include patterns are case-insensitive.

If you choose to reset existing data, only track name, length, manual RVA and empty comment fields will be overwritten, and the latter two are only if you have enabled importing the Replaygain and Comment tags on the Track tab. Removing non-existing files will remove all tracks from the store that no longer exist on the filesystem. Empty artists and records will also be removed.

The builder dialog has separate notebook pages for artists, records and tracks. The settings made on a page only concern the appropriate category (either artist, record or track). The operations and transformations are performed in the same order as they are placed on the page, from top to bottom.

With each mode you can set the priority of data sources for artist names, record titles and tracks independently (highest comes first). Simply drag & drop the lines of the list to achieve the desired order. For example, if you have proper tags in you audio files for track names only, but none for artists and records, you may use metadata for tracks at first place, and use CDDB for artists and records instead. The data sources can also be disabled by clicking on the check boxes.

The Builder looks for usable data in the given priority, and will use the first suitable one.

A short note on the Filesystem source: when using the directory driven mode with structure a), the artists and records will have the same filesystem name, which is the name of the record directory. Using pattern b), c) or d) will result in all artists, records and tracks having the name of their respective directory (or file, for tracks) as the filesystem name. With c) and d), the name of the rightmost artist directory is used. When using the independent mode, artists, records and tracks will have the same filesystem name, which is the filename of the audio file being imported.

Regardless of the data source that won the contest for being the source of your artist, record or track name, you can perform several transformations on this string before accepting it as final.

The main goal of the regexp module is to perform sed-like substitutions, allowing you to extract the artist, record or track name from the string. It has the effect of a sed s/regexp/replacement/g command. The regexp must not match the empty string (the only exception is leaving the regexp entry empty, which disables the whole regexp module). The replacement is allowed to be empty in which case the matched parts are deleted. The replacement may also contain the special escapes \1 through \9 to refer to the corresponding matching sub-expressions in the regexp. See sed(1) and grep(1) for more information on sed substitution and regexp syntax. There is a sandbox where you can enter a string and see how it would be transformed, providing a safe environment for experiments.

These provide some basic fixes, such as removing the extension or leading numbers, converting underscores to spaces, and trimming leading, tailing or multiple spaces. You can use them together with the regexp module as well, in which case only the replacement will be transformed, as expected.

Finally, with this module you can force a capitalization pattern on the string. The force case entry is a comma-separated list of words or expressions that will be left in the form you entered them. An obvious example is the case of Roman numbers.

After the standard modules present for artist, record and track names, there are some category dependent settings. For artists and records you can set the source of the sort name field, for tracks you can decide whether to import the Replaygain and Comment tags, if available.

Once you are satisfied with the settings click OK. A new window showing the progress is displayed, and the store is filled up. You can abort the process if you encounter some error or weirdness, or just want to refine some settings.

Aqualung has extensive support for viewing and editing most metadata formats in use today. This section acts as a reference of the program's metadata-related capabilities and behavior.

Metadata support is implemented in Aqualung by means of the libraries that support the soundfile formats themselves, as well as additional code in Aqualung. That is, no external metadata-handling library is employed. This has not always been the case, and is a result of major refactoring carried out after having poor experience with metadata libraries. This means metadata support is inherently present in Aqualung for all soundfile formats that are compiled in.

The File info dialog (accessible from the Music Store and the Playlist) acts as a graphical shell for the metadata editing capabilities. Its usage is fairly self-explanatory. For read-only tags, the dialog has no editing controls, so the only available operation is viewing the fields, copy-pasting them to another location, or (if the dialog was opened from the Music Store) importing the field to the Music Store database. Embedded images can also be saved to file.

For writable files, the metadata is editable. Each metadata tag present in the file will be displayed in a separate notebook tab. On each tab the information present in a tag is usually organized as a list of frames, displayed in a key:value fashion. The values of each frame are editable, mostly by means of a simple text entry, but in some cases other widgets (such as a drop-down menu) may also be present. The frame itself can be removed by clicking on the frame's rightmost icon displaying a trash can. Some frames cannot be removed, because their existence is mandated by the corresponding metadata standard for the tag. In this case the trash can is greyed out.

Adding new frames is possible via the drop-down box at the bottom of the tab. This box contains all possible frames that you can add to the present tag. Some frames can only occur once in a tag; in this case after adding it once (or if a frame of this type is already present in the tag) it is no more present in the drop-down box.

Adding and removing whole tags is also supported. Just press the trash can icon at the bottom right corner of the tab, and the whole tag will be removed. Adding a new tag is possible via the drop-down box at the bottom of the window. This box contains all possible tags you can add to this file. This depends on the audio file format and what tags are already present in the file (naturally, only one instance of a particular tag may exist in a file).

Aqualung supports mass tagging, that is, writing data from the Music Store into file metadata. The feature can be invoked on a store, artist, record or a single track using the Batch-update file metadata... popup menu item. Supported metadata fields are artist, record and track name, track number, track comment and year. The names are copied from the visible name fields of the artist, record and track, the track number and comment are set from the sort name and comment field of the track, respectively. The year is extracted from the sort name field of the record.

Configuring metdata-related behavior can be done in Settings / Metadata. The file metadata will always be used if available when adding external files (i.e. not from the Music Store) to Playlist. If no metadata is found, the filename will be used as a title string. In such cases the Adding files to Playlist option controls whether to use the basename only instead of the full pathname. You can utilize filename extension removal and substitution of underscores to space as well.

It is possible to select which ReplayGain tag should be used in case ReplayGain information is found in a file. This should be set according to your preference for Album-based or Track-based volume averaging. If the requested field is not found, the other one is checked and if that exists, it is used instead.

For the metadata editor (File info dialog) you can choose whether you want to set the contents of newly added frames on the basis of another existing tag's equivalent frame. For example, if this option is enabled, adding a Title frame to a newly added APE tag will automatically fill it in, provided that there is e.g. an ID3v2 tag in the same file that already has a Title frame. If this option is unset, newly added fields will be blank.

The last group of options controls the preferred set of tags in MPEG audio files. Because these files can have ID3v1, ID3v2 and APE tags in any combination, it is essential to set this to match your policy regarding the tagging of these files. These settings affect creating (via CD ripping or file export) or batch tagging MPEG audio files.

Whenever there is a generic request for some information concerning a file (e.g. Who is the artist?) we do not want to explicitly specify which metadata tag should be used to retrieve the desired piece of data. As a consequence, all tags present have to be checked. However, since not all tags are equally capable of storing well-formed information (think of ID3v1 limitations), there should be a preference order in which the different tags are queried.

The preference order:

1. MPEG StreamMeta 2. Generic StreamMeta 3. Musepack ReplayGain data 4. FLAC pictures 5. Ogg Xiph comments 6. APE 7. ID3v2 8. ID3v1

Aqualung is a ReplayGain-aware music player. You have to understand and use the RVA system in order to make use of this. The RVA system relies on pre-stored loudness measurements of files, which Aqualung normally does by itself (by selecting the Calculate volume... option from the popup menus). However, for files already containing ReplayGain or RVA information, it is possible to use that as the basis of volume adjustment.

One way of doing this is importing the ReplayGain or RVA frame to the Music Store as manual RVA (using the File info dialog opened from the Music Store. In this case the stored value is editable via the Edit track... popup menu item, where you can also specify such a value manually, if needed.

In case there is no manual RVA value stored for the file, the RVA system will see if there is a previously calculated loudness value stored for this track. If yes, this will be the basis of a volume adjustment calculation, which is controlled by Settings / Playback RVA options. However, if the RVA system is enabled and neither manual RVA, nor loudness measurement is available, Aqualung looks for ReplayGain or RVA information in the file metadata. If such information is found, it is used in the same way as manual RVA, so the track's playback gain will be adjusted by exactly the specified amount.

There is an important difference between manual RVA data coming from a metadata tag or specified directly by the user, and loudness values calculated by Aqualung. The former is a volume adjustment in itself, specifying the amount of cut or boost to apply when playing the track. On the other hand, Aqualung's loudness levels merely serve as an indicator of the track's loudness, and are converted to actual volume adjustment values when adding the track to the Playlist, via Aqualung's RVA algorithm, which is a quite sophisticated tool based on listening environments, also supporting statistics-based handling of Album-based volume averaging.

When exporting files, Aqualung attempts to retain the metadata of the original file as much as possible by transcoding metadata into the tags supported by the output format. For each frame present in the input metadata, it is determined whether it is possible to add an equivalent frame to one of the tags supported by the output format. If yes, the frame data is converted and stored. Note that for each frame type (e.g. Title), only one source tag is chosen to be copied from even if it is present in more than one tag in the input metadata. In this case the tag with the highest precedence is used as input. Of course, if more instances of the same frame are present in the same tag (e.g. multiple APIC frames in an ID3v2 tag), they are all transferred if the output metadata format supports them.

This feature essentially means that files are transcoded with intelligent metadata transfer. For example, exporting a FLAC containing Ogg Vorbis comments and two FLAC picture frames to MP3 will result in an MP3 with an ID3v2 having the respective text frames, and two APIC frames for the pictures.

When assembling the metadata written to the output file, the information from the Music Store or Playlist (Title, Artist, Album, Year, Track number) will be used in case the source metadata does not contain the appropriate frames.

This table shows what tag types are supported for which audio formats. Formats for which no metadata support is present are omitted.

ID3v1 ID3v2 APE Ogg Xiph Comments FLAC Pictures Musepack ReplayGain Generic StreamMeta MPEG StreamMeta Module info FLAC R/W R/W Ogg Vorbis R/W Ogg Vorbis (stream) R R MPEG Audio R/W R/W R/W MPEG Audio (stream) R R MOD Audio R Musepack R/W R Monkey's Audio R/W WavPack R/W

ID3v1 and ID3v1.1 (http://www.id3.org/ID3v1) are fully supported. The difference between the two is the presence or absence of a separate Track Number field, which was added in ID3v1.1. Aqualung automatically parses the tag choosing the right version. When writing the tag, it is written as ID3v1.1 if a Track Number frame is present, and written as ID3v1 otherwise.

The Genre field has a fixed set of possible contents in ID3v1 and ID3v1.1. This is enforced by a drop-down menu in the metadata editor GUI.

ID3v2 tags are supported with the restriction that the tag MUST be at the beginning of the file. Tag versions before ID3v2.3 are considered obsolete and not supported. Support for ID3v2.3 tags (http://id3.org/id3v2.3.0) is read-only, meaning that they are parsed, but converted to ID3v2.4 whenever saved back to file. ID3v2.4 tags (http://id3.org/id3v2.4.0-structure) are supported in both read and write mode.

ID3v2.4 tags are always written using UTF-8 as the string encoding of non-ASCII text data, and unconditionally employing unsynchronisation on all frames. Extended headers are neither parsed nor written. Padding is added when creating a new file (via CD ripping or file export) or rewriting a tag that does not fit in its earlier space (e.g. when adding a picture frame, which is usually larger than the remaining padding, thus mandating the re-writing of the whole file). In these cases the policy for determining the amount of padding is that the size of the tag should be an integer multiple of 2K, and the added padding should be between 2K and 4K.

Not every frame defined by the ID3v2 standards is implemented; however, the commonly used subset of the frames is available. In particular, all text information frames (T***) including User defined text frame (TXXX), URL link frames (W***) including User defined URL link frame (WXXX), comments (COMM), relative volume adjustment 2 (RVA2), and attached picture (APIC) frames are supported.

Some ID3v2.3 frames that have been discontinued in ID3v2.4 are supported by reading and converting them to other (functionally equivalent) frames: TDAT, TIME, TRDA and TYER are treated as TDRC and TORY is treated as TDOR.

Note that the RVAD frame in ID3v2.3 is not supported.

APEv1 and APEv2 tags are supported with the restriction that the tag MUST be located at the end of the file, possibly before an ID3v1 tag. Standard items are supported as well as ReplayGain-related frames, and picture frames which are by convention binary items identified by a key starting with Cover Art followed by the picture type definition in brackets. This is compatible with most existing tagging software.

Ogg Xiph comments (also known as Ogg Vorbis comments) are supported according to the recommended field names in the Vorbis format spec. In addition to this, COMMENT, DISC, and ReplayGain-related fields are also supported.

In FLAC files there may be an Ogg Xiph comment block along with separate picture blocks that contain one embedded picture each. This tag is Aqualung's pseudo-tag for referring to the set of picture blocks in a FLAC file, so the only frame you can add to this tag is the Attached picture.

In Musepack SV7 streams there may be ReplayGain data in the file (not in a metadata tag, but in the coded audio data itself). Technically, it is always present, but is only treated as existent when it is nonzero. Aqualung displays (and has the capability to use) this information by referring to it as a Musepack ReplayGain pseudo-tag (which, again, is not a proper metadata tag in reality). This information is read-only.

This is a read-only pseudo-tag carrying information that was obtained when speaking to the Icecast or SHOUTcast stream server. Specifically, the relevant HTTP header fields received from the server are saved in this pseudo-tag and made available for viewing. These currently include the Icy-Name, Icy-Description and Icy-Genre fields.

This is a read-only pseudo-tag carrying information that was received while listening to an MPEG stream on internet radio via SHOUTcast. This information consists of key:value pairs, and is thus fairly similar to Ogg Xiph comments. Usually internet broadcast stations include only a small number of fields, but since the field name is included in the transmission, there is no restriction on the supported fields.

For files handled by the MOD library, some read-only information about the file (number of channels, instruments, etc.) is displayed.

This dialog is the control center of the program, and is a central place to set user-accessible options affecting the behavior of the program. It is accessible from the main window's popup menu, and is split into multiple notebook pages to make arranging and accessing all the options easier. The following subsections describe the individual notebook pages of the dialog.

The General tab itself is further divided into tabs, which are explained below.

The options controlling the behavior of the Main Window speak for themselves. One advantage of combining the Play and Pause buttons is that it allows for starting playback and later toggling between play and pause with the same remote command, aqualung -N0 --play. It is useful if your keyboard has a combined Play/Pause multimedia button and you want to utilize its functionality to control Aqualung via remote commands.

The Title format string will be used to construct a single title line from an Artist, a Record and a Track name when adding songs to the Playlist. The Artist, Record and Track names should appear as %a, %r and %t flags in the template, respectively.

Conditional string elements can be inserted using a ?A1|A2|...|An{CONTENT} expression, where each Ai should be a subset of the available flag characters (that is, the set {a,r,t}). The value of the conditional expression is the logical OR of the individual Ai expressions. The value of an Ai expression is true if all strings are available whose flag character appears in the expression in question (logical AND).

If the conditional is true, the content of the following pair of braces will be inserted, otherwise it will be skipped. The CONTENT string may contain the flags %a, %r or %t as well.

If you want to insert a literal %, ? or } you should write %%, %? or %}, respectively, except for a ? inside CONTENT, and a } outside CONTENT, where they can appear unquoted. Of course it is good practice to always escape these characters for the sake of clarity if one needs them literally.

Everything that is neither a conditional expression nor a flag will be copied verbatim into the result.

Note that the expression ?a{%a} is equivalent to %a since the flags will only be substituted if the corresponding string is available, so there's no need for the extra check.

An example title format is %a?ar|at{ - }%r?rt{ - }%t. Using this format string, one would get the following components, in order:

%a artist name if available ?ar|at{ - } if (artist AND record) OR (artist AND track) available, the string - %r record name if available ?rt{ - } if (record AND track) available, the string - %t track name, if available

The Programmable title format file appears if Aqualung is compiled with Lua support. It allows you to choose a .lua file containing Lua code that determines the title string to use for the playlist, which takes precedence over the above Title format setting.

You can type in the path to the file or click Browse to get a file chooser. The .lua file should be a valid Lua source code file, containing a function named playlist_title, which should accept no arguments and should return a string, which Aqualung will call to get the string to use as the entry in the playlist. The .lua file should also include an application_title function with the same API, which will be used instead of the playlist_title function for programmatically setting the window title. If you would like the application title and playlist title to be the same, you can have your application_title function just call playlist_title.

Aqualung defines two functions for you to use to get data to use in the title format, m and i. m stands for metadata, and i stands for file info. The m function is used to get metadata from file tags, while the i function is used to get information about the file itself, such as the length, bitrate, and number of channels. If there are multiple metadata entries (such as multiple artists), m will return them as a single string separated with comma (,). If there is no metadata entry, m will return the empty string. If you ask for a metadata or file info entry that Aqualung doesn't understand, Aqualung will log an error and will fallback to using the standard title formatting code.

Here are some examples.

@function playlist_title() @ return m('artist') .. '-' .. m('title') .. ' (' .. m('album') .. ')' @end

Results:

  • Yngiew Malmsteen-Far Beyond the Sun (Rising Force)
  • -Greensleeves ()
@function mi(field, format) @ if field ~= "" then @ field = string.format(format, field) @ end @ return field @end @function dirname(path) @ if string.find(path, "/") then @ return string.sub(path, 1, string.len(path) - string.find(string.reverse(path), "/")) @ else @ return "" @ end @end @function album() @ local a = m('album') @ if a ~= "" then @ a = a .. mi('date', ' (%s)') @ else @ a = dirname(i('filename')) @ end @ return a .. '-' @end @function playlist_title() @ return album() .. mi('trackno', '%s-') .. m('title') @end

Results:

  • Rising Force (1984)-01-Far Beyond the Sun
  • irish_music-Greensleeves
@-- Maximum length of a line in the playlist @maxlen = 85 @-- Directory name for path @function dirname(path) @ if string.find(path, "/") then @ return string.sub(path, 1, string.len(path) - string.find(string.reverse(path), "/")) @ else @ return "" @ end @end @-- File name for path @function basename(path) @ if string.find(path, "/") then @ return string.sub(path, string.len(path) - string.find(string.reverse(path), "/") + 2) @ else @ return path @ end @end @-- The album name from the metadata, or the directory name of the file if not present @function album_or_dir() @ local album = m('album') @ if album == "" then @ album = basename(dirname(i("filename"))) @ end @ return album @end @-- The title from the metadata, or the base name of the file if not present @function title_or_file() @ local title = m('title') @ if title == "" then @ local file = basename(i("filename")) @ if not string.match(file, "^%d+%-%....$") then @ title = file @ end @ end @ return title @end @-- If the field exists in the metadata, format it using the format_string @function formatif(field, format_string) @ if field ~= "" then @ field = string.format(format_string, field) @ end @ return field @end @-- A string indicating the frequency in Hz, or the empty string if the frequency is 44100 @function freq() @ local hz = string.format("%i", i('sample_rate')) @ if hz == "44100" then @ hz = "" @ else @ hz = formatif(hz, "[%sHz] ") @ end @ return hz @end @-- A string indicating the number of channels, unless the number of channels is 2 (stereo) @function chan() @ local m = string.format("%i", i('channels')) @ if m == "2" then @ m = "" @ elseif m == "1" then @ m = "[MONO] " @ else @ m = formatif(m, "[%s channels] ") @ end @ return m @end @-- Pad the string to the given length, adding spaces if it is too short and truncating @-- it if it is too long @function pad(s, n) @ local l = string.len(s) @ if l > n then @ s = string.sub(s, 1, n) @ else @ s = s .. string.rep(' ', n-l) @ end @return s @end @-- Combine the left and right sides, with the right side having priority @function finalize(l, r) @ return pad(l, maxlen - string.len(r)) .. r @end @-- Build the title in two parts, a left part (channel and frequency expections, album, @-- track number, title) and a right part (artist, genre, comment, date, and gain). @-- The right part is columnar, the left side is not. @function playlist_title() @ local l = chan() .. freq() .. formatif(album_or_dir(), "%s-") @ .. formatif(m('trackno'), "%s-") .. title_or_file() @ local r = " " .. m('artist') .. " " .. formatif(m("genre"), "%s ") @ .. pad(m('comment'), 12) .. " " .. pad(m("date"), 4) .. " " @ .. pad(m('track_gain'), 5) .. " " .. pad(m('album_gain'), 5) @ return finalize(l, r) @end

Results:

  • Rising Force-02-Far Beyond the Sun Yngwie Malmsteen Metal 1984 -0.89 -0.94
  • irish_music-Greensleeves Celtic 1990 +0.83
@[ title | artist | album | date | genre | trackno | @ comment | disc | performer | description | organization @ | location | contact | license | copyright | isrc | @ version | subtitle | debut_album | publisher | conductor @ | composer | publication_right | file | ean_upc | isbn | @ catalog | label_code | record_date | record_location | @ media | index | related | abstract | language | @ bibliography | introplay | bpm | encoding_time | @ playlist_delay | original_release_time | release_time | @ tagging_time | encoded_by | lyricist | filetype | @ involved_people | content_group | initial_key | length | @ musician_credits | mood | original_album | @ original_filename | original_lyricist | original_artist @ | file_owner | band | remixed | set_part | produced | @ station_name | station_owner | album_order | @ performer_order | title_order | software | set_subtitle @ | user_text | commercial_info | legal_info | @ file_website | artist_website | source_website | @ station_website | payment | publisher_website | user_url @ | vendor | rg_loudness | track_gain | track_peak | @ album_gain | album_peak | icy_name | icy_descr | @ icy_genre | rva ] @[ filename | sample_rate | channels | bps | samples | @ voladj_db | voladj_lin | stream | mono ]

Changing the Programmable title format file entry takes effect immediately, but does not affect existing entries in the playlist. In order to update existing entries in the playlist, the Reread file metadata setting should be used.

This page is present only if Aqualung was compiled with systray support. Even if it is supported, it can be turned off here, which naturally makes further configuration useless. If systray is enabled, Aqualung can start in minimized state a useful feature if the program is launched automatically from the startup script of the window manager.

Mouse button and wheel events on the tray icon are supported and can be assigned configurable commands. You can assign separate commands to the vertical and horizontal mouse wheels. Choose the desired command from the list displayed by the corresponding combo box.

The left and right mouse buttons are reserved for hiding/showing the windows and popping up the context menu, respectively. Any other buttons can be bound to a custom command by adding a new button to the list. In the presented dialog, move the cursor over the test panel and press the button you want to configure. Below the test panel, choose the appropriate action to be taken when you click on the tray icon with the selected mouse button. One button can be assigned only one command at a time. To change an already configured button, remove it from the list first and add it again.

The so-called Implicit command line is something you should pay attention to. It exists mainly for those who have a stable sound setup and always use the program with the same output device, e.g. they have only OSS and don't plan to upgrade. For such users it may be cumbersome to always specify the desired output device on the command line, along with its optional parameters if needed. So here you may enter something that you would otherwise enter on the command line every time.

But beware: you cannot override or turn off every option, so for example if you enter --help here, the program will always display the standard message and exit immediately; and there is no way to override that from the command line. If you get into trouble, all you have to (or can) do is grab a text editor and hack it out of ~/.aqualung/config.xml where it is stored. You will find it between <default_param> and </default_param>.

There are also some options to handle the display of album cover art. This feature is automatically triggered when an image file is found in the same directory as the track being played. The filenames that will at first be looked for are cover.ext, .cover.ext, front.ext, .front.ext, folder.ext, .folder.ext, where ext is one of jpg, jpeg, png, gif, bmp, tif, tiff. If none of them exists, the first image file having an appropriate extension will be used. If you select a record (or one of its tracks) in the Music Store, the image will be displayed in the comment pane. It is also shown in the File Info dialog as well as the main window during the playback of a track from this album. Clicking the image will show a zoomed version of the cover.

When playing files or viewing them in the File info dialog, embedded pictures are also used for cover display. If an embedded picture frame is found in file metadata, it is displayed instead of any separate image file. If there is more than one embedded picture in the file, the first one is used. In these cases no separate image file is used, so the embedded image found in file metadata is displayed regardless of any separate image in the audio file's directory.

There are some global options to set here as well, which should be quite obvious to use.

The Playlist is embedded in the Main window by default to achieve a more compact look. Turn it off to put the Playlist into a separate window.

You can set whether to use Album mode by default when adding songs from Music Store to the Playlist. Regardless of this setting, you can always add tracks without using Album mode by using the Add to playlist popup menu in Music Store.

Settings concerning playlist tabs can be made too. You can control whether to have close buttons on playlist tabs. If you don't want the tab bar to be hidden when only one tab is open, uncheck the Always show the tab bar item.

The option to save/restore the Playlist when exiting and starting the program is turned on by default. If you prefer starting with an empty Playlist every time, turn it off. You can also set whether to save the Playlist periodically. The interval for this is adjustable between 1 and 60 minutes.

Here you can also set the visibility of the track lengths and RVA values in the Playlist. By drag & dropping entries in the list, you can rearrange the columns. The position of those that are not shown is of course irrelevant. Other options should be obvious, such as hiding the statusbar, or showing active track name in bold.

The purpose and usage of Music Store and database files have been covered. On this page you can somewhat customize the Music Store, decide whether to hide the comment pane or the status bar, or to enable rules hint. If you choose to expand stores on startup, all toplevel tree nodes will automatically be expanded after starting Aqualung.

As already mentioned before, this page is also the place to manage music store database files too. Pressing the Refresh button will update the accessibility (r, rw, unreachable) flags of the specified store files.

Changing the two options on the DSP page takes effect immediately, and stays that way regardless of whether you leave the dialog with the OK or Cancel button.

The sample rate converter type should be chosen to fit the resources of your computer, and provide the best affordable quality at the same time. So fire up top or something similar on a spare terminal, and start with the best converter. If your machine is not very new, this will consume huge amounts of CPU, and the playback will very likely be choppy. If this is the case, you will have to pick another converter. Fastest Sinc Interpolator is usable on today's most machines. If not, use Linear Interpolator instead of ZOH since both are blindingly fast, but linear is naturally much better than zero-order (constant hold). It should also be noted that the CPU usage of sample rate conversion is greatly affected by the difference between the two sample rates: upsampling 32k to 96k will be much more expensive than, say, upsampling from 44.1k to 48k.

Of course, sample rate conversion springs into action only when the output sample rate (the sample rate you specified in case of OSS or ALSA, or the sample rate the JACK server specified in case of JACK) does not match the sample rate of the track you are playing. A typical situation is when you have 44.1k files grabbed from CD and play back at 48k.

This page is for setting the RVA options. RVA itself has already been discussed above.

On this page you can configure how the Aqualung metadata subsystem works. See this section for a detailed description.

You can set the drive speed for CD playing in CD-ROM speed units. Lower speed usually means less drive noise. However, when using Paranoia error correction modes for increased accuracy, generally much larger speeds are required to prevent buffer underruns (and thus audible drop-outs), but this is very device-specific.

Most drives let Aqualung know when a CD has been inserted or removed. However, some drives don't report correctly, and thus it may happen that a newly inserted CD remains unnoticed to Aqualung. In such cases, forcing TOC re-read on every drive scan should help.

Aqualung can automatically add newly inserted CDs to the Playlist, and remove them when the CD is removed from the drive. A CD will only be added if the Playlist doesn't already contain any of its tracks. The newly added CD will appear at the top of the Playlist, but after all CD tracks or albums being in the list.

Removal from Playlist will happen if the CD is removed from the drive, or the user quits Aqualung while the CD is in the drive. All tracks of the CD will be removed, even if they were mixed with other audio files or some of them were removed manually.

You can set some parameters of the CDDB lookups here. As for the query protocol, standard CDDBP (port 888) and CDDB over HTTP (port 80) are supported. The standard CDDBP port is the recommended choice unless some unavoidable firewall settings prevent you from using it. For submission HTTP is always used.

The default CDDB database server address is freedb.org, but you may specify another server (maybe a close mirror). The connection timeout can also be set here.

If you want to submit records to the CDDB server, you will have to give a valid email address. Should your submission be rejected for some reason, you will receive a note about the failure to this address.

Retrieved matches are cached in the ~/.cddbslave directory by default. If you prefer an other location instead, specify a local CDDB directory. If you do not intend to download from a CDDB server at all, you can set to use the local database only.

Instead of connecting directly to the Internet you can use an HTTP proxy. In this case you have to specify the proxy server address and port. You may also provide a list of domains that should be accessed without using the proxy. Setting a proxy affects Internet radio streaming, podcast downloading and CDDB lookups.

Timeout for socket I/O is used to prevent Aqualung from hanging if data is coming too slowly or not at all from a radio station.

On this page you can decide whether to override some fonts and colors provided by the skins. You can change the font of the Music Store, Playlist, the track and timer labels, and set the color of the active track in Playlist. Useful if you have problems with font size or your system lacks or improperly renders a font specified in a skin.

You can entirely get rid of all skin settings by selecting Disable skin support. It allows you to flawlessly use a GTK or other theme with Aqualung.

z, Z, y, Y, comma jump to previous track x, X, p, P play c, C, SPACE pause v, V, s, S stop CTRL+S stop after current song (toggle) b, B, period jump to next track left arrow jump (seek) backwards in current track right arrow jump (seek) forward in current track BACKSPACE restart current track / volume down * volume up ALT+/ balance towards left ALT+* balance towards right ALT+S show/hide Music Store ALT+L show/hide Playlist ALT+X show/hide LADSPA patch builder 1 toggle track repeat 2 toggle repeat all 3 toggle shuffle < adjust start of loop range to current playing position > adjust end of loop range to current playing position i, I bring up the File Info dialog for currently played track o, O show Settings k, K show Skin Chooser ESC hide all windows (works only with systray support) CTRL+Q quit Aqualung up/down arrow navigation in the list ENTER, double click start playback of the selected or double-clicked track, or jump to it if already playing a, A scroll list to show active track w, W collapse all nodes +/-, ` (grave) expand/collapse selected node insert add files SHIFT+insert add directory CTRL+A select all CTRL+SHIFT+A select none DELETE remove selected tracks SHIFT+DELETE remove all tracks CTRL+DELETE remove selected tracks from filesystem (confirmation required) u, U cut selected (remove not selected tracks) t, T send selected songs to iRiver iFP device i, I, F1 bring up the File info dialog (also accessible from the right-click popup menu) f, F search in Playlist CTRL+T new tab CTRL+R rename tab CTRL+W close tab CTRL+SHIFT+T undo close tab CTRL+PageDown, CTRL+TAB switch to next tab CTRL+PageUp, CTRL+SHIFT+TAB switch to previous tab CTRL+X cut selection to clipboard CTRL+C copy selection to clipboard CTRL+V paste clipboard before cursor CTRL+SHIFT+V paste clipboard after cursor q, Q, ESC hide window (same as ALT+L in main window) up/down arrow navigation in the tree +/-, ENTER expand/collapse current node w, W collapse all rows double click, a, A add item to Playlist (recursive) n, N new item CTRL+N new child item e, E edit item x, X export item DELETE remove item u, U Build / Update store from filesystem (for stores), Update (for podcasts) v, V start volume calculation for unmeasured items (recursive) f, F search in all stores s, S save store (for stores only) b, B build / update store from filesystem (for stores only) i, I bring up the File info dialog (for tracks only) q, Q, ESC hide window (same as ALT+S in main window)

In addition to the popup menu items and keyboard shortcuts, you can also add an item to the Playlist by drag & dropping from the Music Store window into the Playlist. This method has a further advantage: you can place the newly added items in any position, not just append to the end of the list.

Another trick is that middle clicking on an item in the Music Store adds the content to a new playlist tab, which will be named after the middle-clicked element by default.

aqualung-0.9beta11/doc/aqualung-latex.xsl0000644000175000001440000002754011136163560015351 00000000000000 \{ \} \% \_ \$ {-}{-} \textbackslash{} \textasciitilde{} \& \dots{} \documentclass[10pt,english]{article} \usepackage{ae} \usepackage{aecompl} \usepackage[T1]{fontenc} \usepackage{ucs} \usepackage[utf8x]{inputenc} \usepackage{babel} \usepackage{geometry} \geometry{a4paper,tmargin=3cm,bmargin=3cm,lmargin=2.5cm,rmargin=2.5cm,headsep=1cm} \usepackage{graphicx} \usepackage{color} \usepackage{array} \usepackage[dvips, bookmarks, bookmarksopen=true, bookmarksopenlevel=2, colorlinks=true, pdfview=FitH, pdfstartview=FitH, urlcolor=blue, linkcolor=black, pdftitle={}]{hyperref} \usepackage{fancyhdr} \pagestyle{fancy} \sloppy \lhead{} \chead{} \rhead{\thepage} \lfoot{} \cfoot{} \rfoot{} \begin{document} \begin{titlepage} \begin{center} \hspace{0mm} \vspace{10mm}\\ {\Huge\bf Aqualung} \vspace{3mm}\\ {\LARGE Music Player for GNU/Linux} \vspace{10mm}\\ \today \vspace{70mm}\\ {\Huge User's Manual} \vspace{60mm}\\ Copyright \copyright{} \vspace{5mm}\\ \end{center} \end{titlepage} \tableofcontents{} \newpage{} \end{document} \hyperref[ ]{\color{blue} } \section{ \label{ }} \subsection{ \label{ }} \subsubsection{ \label{ }} \paragraph*{ } \begin{figure}[h!] \centering \includegraphics[scale=0.7]{ .eps }\end{figure} \href{ }{ \includegraphics[scale=0.5]{external.eps}} \begin{center}\begin{tabular}{ l } \end{tabular}\end{center} \begin{center}\begin{tabular}{ |l |}\hline \end{tabular}\end{center} \begin{center}\begin{tabular}{|l |c |}\hline \rotatebox{90}{\mbox{ ~}} & \\ \hline \end{tabular}\end{center} \begin{center}\begin{tabular}{|m{4cm}|m{10cm}|} \hline \multicolumn{1}{|c|}{\textbf{key}} & \multicolumn{1}{c|}{\textbf{action}} \\ \hline \hline \end{tabular}\end{center} \\ \\ \hline \hline & \begin{description} \end{description} \item [ ] \begin{itemize} \end{itemize} \item \noindent `' \textsl{ } \texttt{ } \begin{verbatim} \end{verbatim} \texttt{ } \emph{ } \\ -- aqualung-0.9beta11/doc/aqualung-man.xsl0000644000175000001440000000560411107574203015002 00000000000000 .TH AQUALUNG 1 "" .SH NAME aqualung \- Music player for GNU/Linux .SH SYNOPSIS .SH DESCRIPTION .P Please refer to the documentation available at the homepage for a detailed description of features, usage tips and troubleshooting issues. This manual page is merely an abstract from the User's Manual, and documents only the command line interface of the program for quick reference. .SH OPTIONS .SH FILES .SH ENVIRONMENT .SH AUTHORS .br Tom Szilagyi <tszilagyi@users.sourceforge.net> .br Peter Szilagyi <peterszilagyi@users.sourceforge.net> .br Tomasz Maka <pasp@users.sourceforge.net> .br Jeremy Evans <code@jeremyevans.net> .SH BUGS .P Yes. Report them to our bugtracker at <http://aqualung.factorial.hu/mantis> or write to our mailing list (the subscription interface is accessible from the project homepage). .SH HOMEPAGE .P Please go to <http://aqualung.factorial.hu> to download the latest version, access the Aqualung bugtracker and subscribe to the mailing list. .SH USER'S MANUAL .P The latest version of the User's Manual is available at the project homepage. .TP .br .TP .B .P ` ' \fB \fR aqualung-0.9beta11/doc/aqualung-xhtml-multipage.xsl0000644000175000001440000002576011107574203017355 00000000000000 Prev: . . Prev: . Next: .1. Next: .
[ home ]
Prev: . . Prev: . Next: . . Next: .
[ home ]
Next: .
aqualung-doc-part_ .html aqualung-doc-part_ _ .html # && index.html <xsl:value-of select="/aqualung-doc/titlepage/title"/>

Table of Contents


&& <xsl:value-of select="/aqualung-doc/titlepage/title"/>


&& <xsl:value-of select="/aqualung-doc/titlepage/title"/>


aqualung-0.9beta11/doc/aqualung-xhtml-view.xsl0000644000175000001440000000034111107574203016324 00000000000000 the fly aqualung-0.9beta11/doc/aqualung-xhtml.xsl0000644000175000001440000001620511316415632015364 00000000000000 <xsl:value-of select="titlepage/title"/>

Generated on


Copyright &copy;

Table of Contents

. . . . . .

[screenshot]

keyaction
center
  • `'

    &ndash;
    aqualung-0.9beta11/doc/external.eps0000644000175000001440000000601711107574203014216 00000000000000%!PS-Adobe-2.0 EPSF-2.0 %%Title: external.fig %%Creator: fig2dev Version 3.2 Patchlevel 5-alpha5 %%CreationDate: Thu Mar 29 20:02:05 2007 %%For: sailor@crux (Peter Szilagyi,,,) %%BoundingBox: -5 0 16 16 %Magnification: 1.0000 %%EndComments /$F2psDict 200 dict def $F2psDict begin $F2psDict /mtrx matrix put /col-1 {0 setgray} bind def /col0 {0.000 0.000 0.000 srgb} bind def /col1 {0.000 0.000 1.000 srgb} bind def /col2 {0.000 1.000 0.000 srgb} bind def /col3 {0.000 1.000 1.000 srgb} bind def /col4 {1.000 0.000 0.000 srgb} bind def /col5 {1.000 0.000 1.000 srgb} bind def /col6 {1.000 1.000 0.000 srgb} bind def /col7 {1.000 1.000 1.000 srgb} bind def /col8 {0.000 0.000 0.560 srgb} bind def /col9 {0.000 0.000 0.690 srgb} bind def /col10 {0.000 0.000 0.820 srgb} bind def /col11 {0.530 0.810 1.000 srgb} bind def /col12 {0.000 0.560 0.000 srgb} bind def /col13 {0.000 0.690 0.000 srgb} bind def /col14 {0.000 0.820 0.000 srgb} bind def /col15 {0.000 0.560 0.560 srgb} bind def /col16 {0.000 0.690 0.690 srgb} bind def /col17 {0.000 0.820 0.820 srgb} bind def /col18 {0.560 0.000 0.000 srgb} bind def /col19 {0.690 0.000 0.000 srgb} bind def /col20 {0.820 0.000 0.000 srgb} bind def /col21 {0.560 0.000 0.560 srgb} bind def /col22 {0.690 0.000 0.690 srgb} bind def /col23 {0.820 0.000 0.820 srgb} bind def /col24 {0.500 0.190 0.000 srgb} bind def /col25 {0.630 0.250 0.000 srgb} bind def /col26 {0.750 0.380 0.000 srgb} bind def /col27 {1.000 0.500 0.500 srgb} bind def /col28 {1.000 0.630 0.630 srgb} bind def /col29 {1.000 0.750 0.750 srgb} bind def /col30 {1.000 0.880 0.880 srgb} bind def /col31 {1.000 0.840 0.000 srgb} bind def end save newpath 0 16 moveto 0 0 lineto 16 0 lineto 16 16 lineto closepath clip newpath 0.8 14.9 translate 1 -1 scale /cp {closepath} bind def /ef {eofill} bind def /gr {grestore} bind def /gs {gsave} bind def /sa {save} bind def /rs {restore} bind def /l {lineto} bind def /m {moveto} bind def /rm {rmoveto} bind def /n {newpath} bind def /s {stroke} bind def /sh {show} bind def /slc {setlinecap} bind def /slj {setlinejoin} bind def /slw {setlinewidth} bind def /srgb {setrgbcolor} bind def /rot {rotate} bind def /sc {scale} bind def /sd {setdash} bind def /ff {findfont} bind def /sf {setfont} bind def /scf {scalefont} bind def /sw {stringwidth} bind def /tr {translate} bind def /tnt {dup dup currentrgbcolor 4 -2 roll dup 1 exch sub 3 -1 roll mul add 4 -2 roll dup 1 exch sub 3 -1 roll mul add 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} bind def /shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul 4 -2 roll mul srgb} bind def /$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def /$F2psEnd {$F2psEnteredState restore end} def $F2psBegin 10 setmiterlimit 0 slj 0 slc 0.06299 0.06299 sc % % Fig objects follow % % % here starts figure with depth 50 % Polyline 0 slj 0 slc 7.500 slw n 0 225 m 157 225 l 157 67 l 0 67 l cp gs col9 s gr % Polyline n 90 0 m 225 0 l 225 135 l 180 90 l 90 180 l 45 135 l 135 45 l cp gs col7 1.00 shd ef gr gs col1 s gr % here ends figure; $F2psEnd rs showpage %%Trailer %EOF aqualung-0.9beta11/doc/timer.eps0000644000175000001440000002003511107574203013510 00000000000000%!PS-Adobe-2.0 EPSF-2.0 %%Title: timer.fig %%Creator: fig2dev Version 3.2 Patchlevel 5-alpha5 %%CreationDate: Sat Mar 24 12:36:59 2007 %%For: sailor@music (Peter Szilagyi,,,) %%BoundingBox: 0 0 173 97 %Magnification: 1.0000 %%EndComments /$F2psDict 200 dict def $F2psDict begin $F2psDict /mtrx matrix put /col-1 {0 setgray} bind def /col0 {0.000 0.000 0.000 srgb} bind def /col1 {0.900 0.900 0.900 srgb} bind def /col2 {0.000 1.000 0.000 srgb} bind def /col3 {0.000 1.000 1.000 srgb} bind def /col4 {1.000 0.000 0.000 srgb} bind def /col5 {1.000 0.000 1.000 srgb} bind def /col6 {1.000 1.000 0.000 srgb} bind def /col7 {1.000 1.000 1.000 srgb} bind def /col8 {0.000 0.000 0.560 srgb} bind def /col9 {0.000 0.000 0.690 srgb} bind def /col10 {0.000 0.000 0.820 srgb} bind def /col11 {0.530 0.810 1.000 srgb} bind def /col12 {0.000 0.560 0.000 srgb} bind def /col13 {0.000 0.690 0.000 srgb} bind def /col14 {0.000 0.820 0.000 srgb} bind def /col15 {0.000 0.560 0.560 srgb} bind def /col16 {0.000 0.690 0.690 srgb} bind def /col17 {0.000 0.820 0.820 srgb} bind def /col18 {0.560 0.000 0.000 srgb} bind def /col19 {0.690 0.000 0.000 srgb} bind def /col20 {0.820 0.000 0.000 srgb} bind def /col21 {0.560 0.000 0.560 srgb} bind def /col22 {0.690 0.000 0.690 srgb} bind def /col23 {0.820 0.000 0.820 srgb} bind def /col24 {0.500 0.190 0.000 srgb} bind def /col25 {0.630 0.250 0.000 srgb} bind def /col26 {0.750 0.380 0.000 srgb} bind def /col27 {1.000 0.500 0.500 srgb} bind def /col28 {1.000 0.630 0.630 srgb} bind def /col29 {1.000 0.750 0.750 srgb} bind def /col30 {1.000 0.880 0.880 srgb} bind def /col31 {1.000 0.840 0.000 srgb} bind def end save newpath 0 97 moveto 0 0 lineto 173 0 lineto 173 97 lineto closepath clip newpath 1.4 97.8 translate 1 -1 scale /cp {closepath} bind def /ef {eofill} bind def /gr {grestore} bind def /gs {gsave} bind def /sa {save} bind def /rs {restore} bind def /l {lineto} bind def /m {moveto} bind def /rm {rmoveto} bind def /n {newpath} bind def /s {stroke} bind def /sh {show} bind def /slc {setlinecap} bind def /slj {setlinejoin} bind def /slw {setlinewidth} bind def /srgb {setrgbcolor} bind def /rot {rotate} bind def /sc {scale} bind def /sd {setdash} bind def /ff {findfont} bind def /sf {setfont} bind def /scf {scalefont} bind def /sw {stringwidth} bind def /tr {translate} bind def /tnt {dup dup currentrgbcolor 4 -2 roll dup 1 exch sub 3 -1 roll mul add 4 -2 roll dup 1 exch sub 3 -1 roll mul add 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} bind def /shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul 4 -2 roll mul srgb} bind def /reencdict 12 dict def /ReEncode { reencdict begin /newcodesandnames exch def /newfontname exch def /basefontname exch def /basefontdict basefontname findfont def /newfont basefontdict maxlength dict def basefontdict { exch dup /FID ne { dup /Encoding eq { exch dup length array copy newfont 3 1 roll put } { exch newfont 3 1 roll put } ifelse } { pop pop } ifelse } forall newfont /FontName newfontname put newcodesandnames aload pop 128 1 255 { newfont /Encoding get exch /.notdef put } for newcodesandnames length 2 idiv { newfont /Encoding get 3 1 roll put } repeat newfontname newfont definefont pop end } def /isovec [ 8#055 /minus 8#200 /grave 8#201 /acute 8#202 /circumflex 8#203 /tilde 8#204 /macron 8#205 /breve 8#206 /dotaccent 8#207 /dieresis 8#210 /ring 8#211 /cedilla 8#212 /hungarumlaut 8#213 /ogonek 8#214 /caron 8#220 /dotlessi 8#230 /oe 8#231 /OE 8#240 /space 8#241 /exclamdown 8#242 /cent 8#243 /sterling 8#244 /currency 8#245 /yen 8#246 /brokenbar 8#247 /section 8#250 /dieresis 8#251 /copyright 8#252 /ordfeminine 8#253 /guillemotleft 8#254 /logicalnot 8#255 /hyphen 8#256 /registered 8#257 /macron 8#260 /degree 8#261 /plusminus 8#262 /twosuperior 8#263 /threesuperior 8#264 /acute 8#265 /mu 8#266 /paragraph 8#267 /periodcentered 8#270 /cedilla 8#271 /onesuperior 8#272 /ordmasculine 8#273 /guillemotright 8#274 /onequarter 8#275 /onehalf 8#276 /threequarters 8#277 /questiondown 8#300 /Agrave 8#301 /Aacute 8#302 /Acircumflex 8#303 /Atilde 8#304 /Adieresis 8#305 /Aring 8#306 /AE 8#307 /Ccedilla 8#310 /Egrave 8#311 /Eacute 8#312 /Ecircumflex 8#313 /Edieresis 8#314 /Igrave 8#315 /Iacute 8#316 /Icircumflex 8#317 /Idieresis 8#320 /Eth 8#321 /Ntilde 8#322 /Ograve 8#323 /Oacute 8#324 /Ocircumflex 8#325 /Otilde 8#326 /Odieresis 8#327 /multiply 8#330 /Oslash 8#331 /Ugrave 8#332 /Uacute 8#333 /Ucircumflex 8#334 /Udieresis 8#335 /Yacute 8#336 /Thorn 8#337 /germandbls 8#340 /agrave 8#341 /aacute 8#342 /acircumflex 8#343 /atilde 8#344 /adieresis 8#345 /aring 8#346 /ae 8#347 /ccedilla 8#350 /egrave 8#351 /eacute 8#352 /ecircumflex 8#353 /edieresis 8#354 /igrave 8#355 /iacute 8#356 /icircumflex 8#357 /idieresis 8#360 /eth 8#361 /ntilde 8#362 /ograve 8#363 /oacute 8#364 /ocircumflex 8#365 /otilde 8#366 /odieresis 8#367 /divide 8#370 /oslash 8#371 /ugrave 8#372 /uacute 8#373 /ucircumflex 8#374 /udieresis 8#375 /yacute 8#376 /thorn 8#377 /ydieresis] def /Times-Bold /Times-Bold-iso isovec ReEncode /Helvetica /Helvetica-iso isovec ReEncode /$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def /$F2psEnd {$F2psEnteredState restore end} def $F2psBegin 10 setmiterlimit 0 slj 0 slc 0.06299 0.06299 sc % % Fig objects follow % % % here starts figure with depth 51 /Helvetica-iso ff 317.50 scf sf 2025 1305 m gs 1 -1 sc (07:47) dup sw pop 2 div neg 0 rm col1 sh gr /Helvetica-iso ff 317.50 scf sf 675 1305 m gs 1 -1 sc (-05:42) dup sw pop 2 div neg 0 rm col1 sh gr /Helvetica-iso ff 476.25 scf sf 1350 630 m gs 1 -1 sc (02:05) dup sw pop 2 div neg 0 rm col1 sh gr % Polyline 0 slj 0 slc 7.500 slw n 585 495 m 675 585 l gs col0 s gr % Polyline n 675 495 m 585 585 l gs col0 s gr % Polyline n 585 1080 m 675 1170 l gs col0 s gr % Polyline n 675 1080 m 585 1170 l gs col0 s gr % Polyline n 2070 495 m 2160 585 l gs col0 s gr % Polyline n 2160 495 m 2070 585 l gs col0 s gr % Polyline n 2070 1080 m 2160 1170 l gs col0 s gr % Polyline n 2160 1080 m 2070 1170 l gs col0 s gr % Polyline n 1800 1080 m 1890 1170 l gs col0 s gr % Polyline n 1890 1080 m 1800 1170 l gs col0 s gr % Polyline n 855 1080 m 945 1170 l gs col0 s gr % Polyline n 945 1080 m 855 1170 l gs col0 s gr % Polyline 15.000 slw gs clippath 180 1003 m 180 1230 l 270 1230 l 270 1003 l 270 1003 l 225 1183 l 180 1003 l cp 270 662 m 270 435 l 180 435 l 180 662 l 180 662 l 225 482 l 270 662 l cp eoclip n 225 450 m 225 1215 l gs col0 s gr gr % arrowhead 7.500 slw n 270 662 m 225 482 l 180 662 l 270 662 l cp gs 0.00 setgray ef gr col0 s % arrowhead n 180 1003 m 225 1183 l 270 1003 l 180 1003 l cp gs 0.00 setgray ef gr col0 s % Polyline 15.000 slw gs clippath 2520 662 m 2520 435 l 2430 435 l 2430 662 l 2430 662 l 2475 482 l 2520 662 l cp 2430 1003 m 2430 1230 l 2520 1230 l 2520 1003 l 2520 1003 l 2475 1183 l 2430 1003 l cp eoclip n 2475 1215 m 2475 450 l gs col0 s gr gr % arrowhead 7.500 slw n 2430 1003 m 2475 1183 l 2520 1003 l 2430 1003 l cp gs 0.00 setgray ef gr col0 s % arrowhead n 2520 662 m 2475 482 l 2430 662 l 2520 662 l cp gs 0.00 setgray ef gr col0 s % Polyline 15.000 slw gs clippath 1813 1350 m 2040 1350 l 2040 1260 l 1813 1260 l 1813 1260 l 1993 1305 l 1813 1350 l cp 887 1260 m 660 1260 l 660 1350 l 887 1350 l 887 1350 l 707 1305 l 887 1260 l cp eoclip n 675 1305 m 2025 1305 l gs col0 s gr gr % arrowhead 7.500 slw n 887 1260 m 707 1305 l 887 1350 l 887 1260 l cp gs 0.00 setgray ef gr col0 s % arrowhead n 1813 1350 m 1993 1305 l 1813 1260 l 1813 1350 l cp gs 0.00 setgray ef gr col0 s % Polyline 15.000 slw n 0 45 m 2700 45 l 2700 900 l 0 900 l cp gs col0 s gr % Polyline n 0 900 m 0 1530 l 2700 1530 l 2700 900 l gs col0 s gr % Polyline n 1350 900 m 1350 1530 l gs col0 s gr /Times-Bold-iso ff 222.25 scf sf 360 1215 m gs 1 -1 sc (L) col0 sh gr /Times-Bold-iso ff 222.25 scf sf 2205 1215 m gs 1 -1 sc (R) col0 sh gr /Times-Bold-iso ff 222.25 scf sf 2205 630 m gs 1 -1 sc (R) col0 sh gr /Times-Bold-iso ff 222.25 scf sf 360 630 m gs 1 -1 sc (L) col0 sh gr /Times-Bold-iso ff 222.25 scf sf 990 1215 m gs 1 -1 sc (R) col0 sh gr /Times-Bold-iso ff 222.25 scf sf 1575 1215 m gs 1 -1 sc (L) col0 sh gr % here ends figure; $F2psEnd rs showpage %%Trailer %EOF aqualung-0.9beta11/doc/external.png0000644000175000001440000000054211107574203014210 00000000000000PNG  IHDR 2ϽsBIT|dtEXtSoftwarewww.inkscape.org<IDATϿjPl$>S;B.CޠᚼCȞ.K&t8ˏ~F_ {3`2Iׂ"W^m۫{Y_:{IR00f a8c%I,ǣC0ZTR7,Χk9Ǖl@y( nE`<6L`H/Tk>WW*N'/Pn7|l/ VIENDB`aqualung-0.9beta11/doc/jack.png0000644000175000001440000006514411107574203013307 00000000000000PNG  IHDRpmbKGD pHYs  tIME #;p IDATxyU~Ȣ2g%4=.>,$HF~Oia.(bbbd^2/(xgUZ}MiOF _Ym bbbB4p s;`̽ 6DDD]#FrEڍHP8÷3H$?MgD`B.H$|/R?WPD"HBNE }! cmB1^1Bj(gLG \ChW// D"gy~*~/.^^pd^A^<ƻ@m^D`ܶ_b(:*i38# ںme)$%`YLW]оr !*vhXjvd w}e0ϯ_% }a-ӾR߮~^}g[H$?iI$?_pJ-pӎo0?.g 0O"d[#2ދqqMl9SpXDl7;l}/AH_%f_h'C} _/\D fk]S`p,/7=1'9eZB.014SS%N͸zxISq*J6G?~Db0-A[^L9"BN R__iq)9+"t\F ^@]3 gO5OKlWc6$PvM+v0m .'Ccᔚg(3,nqpSIRDDwUTzlS=bl;eΤׯܰu;m2Za]y.]yN<v@pXtwc8dkWe[7;S(}WKTLl}eWٮ "lWժ@0Rspl<"6h7"3"DbX KE-ܯReշK ~þ::þ:~b$x3FW,^a/^nܾ f23[4w _,~I[Zw۞Ga0a~r2/_ŝI:5.Laoc-ۧ76x o\N5L@z@ }t-3fn>n__kyC}1rx&y/- !q c9^9My{x; 37o#ce;d d vоo Bv79xvmv#"~nıs\}Danq - B愒ݶNvgO6æٓ]Q-:B$RXO3= KpH$϶2ЙOc6SP߲|W1Ko`a'`bbb٩'ZsfOçOÕ䋊KނxB?-k2y!Qqg]K`<!&.l=~V8l˺--W3a߮ٮ_+lxFv }/[v7vY_vyΈ"vo̞Yv<5%B9:ݶ9Bor2 4&tnŒ7믠}ŏ#G/v~/$:< ۶ӲC?g'^~74N>Ju(gG>}(y̜9m;:;:drn`qerSv`XDVΟ98ד dݝ zo1Yl"CWҳ\ &Kwi7^97#NcU:8C*'E5v 3g׳n+z;ISYaA^=>|'!,fszH;Uǜ +801庥,x'Cp2XkOΟv#PŋJCJKIHKoĩ^ g]q:?O|?㧔WB@gҚmV O\k>,m#r8I;>+v5Ev$HnĻukGvBuRCSY!}m!fn_o v xySnݺl5G87б(OGWC\{m{C[nUo<}޼Tʕt&X˟_0vLYE%4uB lnj~2}zai]NVlv7 fc&Y>Cc/ƶ5GWoپ ³P1q}V֢ dNjJx D㽽MBBDDL&S(\8PDDssJX, P(qN[UŦ 3";{xyخ_33[qŷzA4;;oq~gߚ I;e;z~yGwݯX8l;fun-4ԙxlJ쩤;ݨ\x^RLLltU[-45!^|v2TRj\557\sٔx\Z0l1Gz[711jU+^0s ^xyՉ Kb&UN5ߺSNdhaXℼ9z)m ]ΈNMԙ{3}$/k5Xe]E{d d~ d0]j6g홣Lg; }&XLܳ;S%Tr|$ ?voB/lWxb)agc{KpWH3b3',nw);9?}ۯ?WDKᴍHPNܶT޽eÚ n: $dk23Md @;-.O;A~,58=Z_=!+u@v aRYTڗݯS繢8~;'bWV9_6#r.ֽ6sy/\k2(8A~eZ["﹥ Yo(oQށBCvXN'osv2\o8DǖEU \ L>Fo _ Olm{t2<Q`)x'L޽{bllli|buX&zcۈb "BB vk}x^HW4|Cx-.(*~% .. d25}Hj.HM}K0)R?&.|q( Ee+ǎ2 <+-STVlwsdd.s[g)!ݽs/5;ڍ;c͋ߖ \kii=v,v!-V#0ëGA&PLL\ASC ƎZZ/pтz:!_Кcc L=q2Aȸs;3NuyJ} ׷nZZO51~ɿ[;ETr C*:wj?42AA}~#':.Z\~ܓǏ͙3s~W\qtӒQ#ccZ7( )I$Tc}]֞6֭ܺϟOII՚<~ ΋]Y,VtTee%O<- f3ԉY3goMJ:pHxV;Nnj9g\'>޽zSBw޹{s^]x /777]~症CC۾F5|eyYy*BHFOې22|m! .ooO 3DLh7?:;-CgݼRPI;r$kٓpX,t#&Op!u '**>zzccki[6oB557.[bl4EQQ!$**p:grCnXknn3hGY[[aL&-ŔsXI璽Wģcav 2CڶdGEsEEijBikMFmY|:ld-\8!FymR.^d2B:Zbb/gdܘ=kqG8Mg_p7nii#G{_ ?LA~!;_Xw]:kyo߾b@\\o߾~y.O# _ag8,};w9 Z̜[q'͵CVpݮ8~v m@+*g:oNaJJJ< ""bbbuTYY Ia+ׯͬnhN ڱ_߾je5LN:wٳ; *++e_Hl@:]A~X͜##Hs^NNNر[|9ca6nݰNFV&"`04Ǎ%3gXoڴe 8=kF۩tt9l2ó]B\vʵK<{=x#(gZsQ"q@v]]dd@v@v]߁/4j "heח]hfߟ]**2]_vT?Z=;gj@v Rp7sflnS{'*dd#]r4/o,*pCےGŮ"""xl'ɳڷK -OǏ-lt)/JKM1ͽ-X~V~8ʪJˠ]"H=dg5qƘ̬=C̛>r߁/SȘŏ6n& ¡c΂͂vYe0O:aReePN- v:YAol -5r۷ttp՜|au=qq1Pmm-&?~dd4e(U3Sɀ\,:o޾+ח+,&k[.<6qqnLtܼKQѧO bjnޝ􌊊繹Ϟ5b0y_~DFE0qx젔T|l4fAET!$''&O2x /dF3!W1nBhضX27>!uG7 tM'B(:&uh!ҮdJ4cX?XlLϞ=N%$VzEc#ׯfi# e=yR-fxQen9ݻŋW{{5B]m[Wg&Ot,8ͮ=gnc#]__pHd2C9Pz^i +§k5}X U^+@val2A)~~>\B&hMay;v&"O—m"f#68W~хAJJvNw0l.ƌ6+&Mm~Ԥ:Ru2bxc#f.+'O%rX˲E$)fAyfaGJJJM22'Oc]z)Sӛ6ܽo4ڿٰy46߿WUqf蓛oda]Ϟ=}}W|g`g`k_*&MțZ2?j;4#c3fYtׯ]dd4ERR+@MMMЎ݃sG@XhpcDIff1Bex~$$$/u 32o-;BEM0k"KۿوfNiNƦy,'`A;3tH%ŞJ/_zgD3S3S%Aed"ùNY[[Y[[NEQ8ӧwTD}%ǵ M!t>4gdӒNT"I<{VcPee%~VRRƨJD{yk spH=;I$|7nX'#+Ic0ҽ~VSђ?L~ܼ{Õ; [;Xޢ>!T_11>{cg[o \lqG㏞dֽn6QTBioQW~̕q"H<!t.%,Q066466:H"VyXB0(Zcɾa+}NI_ON?qlLAYo_bQv#kPbǽ=]D:-]9l`K=,͍\Isrx񚜜x,==-|Hȑ~v>L8ە ǼE܈DbEsh_i}:Ԇs9lVVf:)KD"A2ʪUnR=fϞ=ZW+O$33NORQQw_HORR?h"kk˯[vZڍ#ӯD7NѱvfN677޴)hJt -/Do{ٙP]]bbBYV/]᱆)SSCv@kѲҔsȑ󃃃g̝H@C ? y%%yQEE)-휬 ^ïdKm&bS Z F}MM%55  )\}!Lf3> ?=R(ݞ=k} QQ=.l,j?N%Dbc];wv$DBRRMÇW9cUW+-O\pii^]]5*B66_2!4aݜ9;T*-.wlupL;}FF\8wWf9nB%^oEdBu\U4 us;K .tڊzv4~= h+?e33a Z*Cd-Yve~CtAٍ/;d{YP 1۬ɻ-O.&SSگـN7>HcTʝ3p7|*CeB+=y36:Fw c~#خ֨!sY{3".VL#-)V\jg|fq+ V=#,)|~1T7d!^֤|U ZK., 0fyϪM9xO˹SDExN뮳f,QK̼"y`>nLo> ,&\h]Q$LN˚I-BojN_TŤw ^emM:L.dՌs4!oś1E53Y!F3zVt2@W V"S5n/iH$O!͢rƈV5PV܂1D6{F˜KϗϿvw2I~vAvS]En-47M2PO}@*Zgltq.囌Wz])_DKq?΁1B({,CȂPDHs]}dlg lǍ'8YhǴUsBYEeۏe৮yOr8pd2Y`GX||<>DI-03[Vx:(.< Y3S ۷s{M)`o:VM_JN A_ ˗TgݧƦ]qQ{t>L?9wΓ PDH0HG!IU@:5k EEʪj&vkKO&RKFaٰVFaw0?J˫k9 %4j0uTvN]/]d#.m]B"'U2=$pk8}!r|hm~Eg^󱡩iU_= d:[$ۺʹ0 gkOi֣iۘxF`~qqyza3zz3?;Xl"#i G$ӛ8eu39+ltRoTzϳ*Cdfyp?Tv4/_>-/? Էt?o\dfrp܏mpDZy#/k9 d9t&30n#jaBEp HvnicHIM4n}j |ܲP7oڣFi͟䉐.4 UT&X8y 21b-!r%֖2Q_ZzzVtt1\'!AA0IIjjztz#YY >p:n_27JL%Kp4O݆,F;teeO t:ꡪrXhllX߾rV'^^>6'NDL p B($$*!᜿Ǐ݋Juo8|Oihqw_sH77iLI.qqqIee,98vf'OFΚ_`RR ( B衣 :_pE9;/H>v,zFo[dhnnqu)*#(9~^NN!$/?4+0yz BH]}4͍i]h#.1B!=!dɢ+7Wvv}߳gL-[ Hbڴ ;z_d]MvG蝏*ssLid,(!T\\pʮtwoVTTrm߿߬YV654FN*LDkۆzuu&Ny*4]LLdB"""Jss+WҜ/^&'';~KOO 62;r$~e)--G-ZF$+*C?f]]" tr b'O66;'^${@ O+d8?7ɗ-D"?d2eYmϞ.\΅ lw.*** PSS{ȱ5k?(0p7naii7F <!9͍7m LI9Iؠ|=m=eWJJL&'%>}ZsPee/KJJ:uB!08eea"NWPw6doo[VOD1.|޼yw@m0 QQjj i t7o <$ϲ~e N|b5':wھ}cxQ##-[+++P s8:9`2Y '[n R|i2++s_mN/_<())!|>~$)1Ś1Ò~`ঈ3>&&[99Y/eaaЃOt2 -<˝r_fҚ/|Ds$H^^^^\9ߦʹ+$@&\SSO Yveʡ\4 WDL&dFG! o#.]X󔒒<$?~fe5O^11LM @vxQ,/?$"(O oV 1A]]%%M(;.?g\GVU՚;P' ,lҥ$iCqqatv^NFY䳺w5;wkjj[SSS[]d:#]`~3ū_=

    ]:c՝-`z,Notuר>U-( @Gbb>H|*33g-!NE>x.x#BCi ,v-x nͻhEӧڨ޹QOO NJXs߾ݯ_ݻ@vftE>O , 7| E>]=zxdd@v@v@v]]d~JJ:OG@vdf >d_AiiʕX,T.tRRR,((WQ```uD"W|֬Y&X[aRt:ul yAXõLGdkK-*zȕzQQqŞ66в Щ򱷷9q"f_ WS ..+Y,v7[0 IDAT# B%ط,Bɗ͍űݵk7,8y2r֬RAD%$_w޽{Q x::PdXN__vihV0Af04ZܴiGknnqu)*#(篵_d]MvGCp>>`f0Lidhvm10F-]UQQ^\\pnj}>6ngEE%).tjmCCX|WZ{7+**ss[?}ʕ4''Ɏ·gĉc]))ɸpZȍH$VTbbBYV/]᱆)SSC]-)**Jiidee<]133.A@= < uF'-ud:SeWٓPqv@v@v]]d:&A}SQvN ="|X?$d7T .?6iB55U7~^vod\Z~8zƿ8rS٧NE()yܷoߥKaߵPqq BHEEiݺAAnKJj{RRMo_vnm۶-^i!b#?S[[7f njə-_Jϯ o|ƚB! SR~|꣗Ⱌ>`f0Lidhvm10F-]UQQ^\\pEիvEEڵ׬<.BP}6mhJKwwqY{/=fEEenn_d5995xKm###Gb٩0qXlWJJ2..~ -r#-50l6KKۺݡuN2@&r.f]]" t͍^~|ڂH$3H&"xUz•hذ>B@g$33NORQQw_HORR?h"kkKN7n·n9~$$ݽ[tllndssM&EXwݺnqqInN òBB݆$IIFFOy!I QQjj ip t7o <$6oY> opk6xM:;,,z`bbᱦ_UU;vR狈@l:#[n R|aݻKm߾1>#TL&AS^P(\UUU݈l͍<Hhh(40&AQZZ(;.? 6{JWbĈIT)]~<.\?}X :Nv-_PPdmm2ĉD0yy66TUU-UUYM$%de233|CAvB,p--#&Rre^TTDF555ػwvd:^^>6'NDL p ~e%Ţ?~DYYsBܸ |X\\]v˂'#g/0))PHHTB9uǏݻ^_߀g衣 :_@tÇxRGb(MǏ׀%?ի=,,LB 7mZњ[\]FFz! ryk/99ٿ{W}ܠ*;)Stxa2Y4Z][ BAA~KzUTTb8:-\h@p޼yfGP_587 }}m|P/22ߕ07^z͊wq133MӕHEֶ. m#[RQuחҍ)K"!w4 ͜ǞoM#I*?fΜ9<3yɓoܭi&{H[[Kƒ}`vmfCTVVVU=|mdXvÜ9={L0"//7.(SR` 7nzyŅxvok+g8QfUU[D"Y&&YPr\6~|y*ۼ`ܹs'>oavqk+KJ sr~iӂbIr,(R8n|Ϟ=PZZzƍs@DhgD;,-egolr U渥QgS9/1X7o^8x07~ss`GM .žiύ k߾2Ú6@[iff~O+W܍.z$jkk9;;<޽ b6ևWc~lBB;v*66IUU$466HO_!(n[pp#{+~H 14/,<$FYإK5k~žFHvz۷g mT;(ݼ5U zc.\NIY|_S葘bgg}y]\Ϟ-yyc%Kv:PXx۲jպݕqXW~1YY3fLvpzZG\]Pp},#~9lDP(W<0aPGHr_EE%}chmߞ]\USRK7= oݺ,""ŒO,=oU\ʕiWO>rޕ嗔ΙWweddSS3޸!{422K ЪJ71Ckz$2vDO]&jrDW׉23W[ݷp@/ib"M.@kh#d@ v .b ]. vsC\bޗ^^Y`v}./^XٳAA-]V._TT6tsYo33K33Kww/v .wsγcǞlB!ȑ_=K@B$IrKˑ} .)P ;wfzywsݻrPhQQ1/b 4cu_&u}zƌ%IzM֚GB\\KK/1$dgsqqTRRbϛ1lYEllҎ{*~۶qq?lڴsN/^Toԩ3 ݻw?/=[|y%lkv6{vQNsOD"Qzz֘1#^`cdd@;nL6G'~9-0*jsLsODYX,IO߸xq0B…3gW0^:o 73#&M9VRܹGg0O;tP1c׮͌N |}OnB=%}^4l._P9UUO\pL!}igHOxlIRRtǝ99}nnݴUTO.B NN ={ L0ݻȹo@ TW ;tP'0"n8߸o-.nP(44/,<~Kjj<oǎ=W\儐::ݙv0~/,XZ]-44;z 3iGTP--ʹ "\Ȑ#Ƨf~&hjv4eV[Y IɮuA yD W{zzoߞŞB,fn+WGzxx du LJIK('';9DGvuUUUK IM͸~\VSbn3g ޽?@#@hh[g"{kt7QnnwoaWWWxѣGS Zr!!!!30ZVhht\4G >bX޺c!h,.)leeW]]'jjv\bou߾sd4rp4YWJMd`wҩ&,hjjSK t+euY2'5EQn\왋xs6c"v vZd /VN7TAC Jcg 3]]ASbg -6voh.. @ v .b ]vFv/5^5vNmj,Ő жBۂ].b]@ vhgdR34EQ m -(;ԘPc ^42(.b1sr״;w*b1 v;ݸm׮]G{.Dy׮]zߢw:zTO]].Ei쪫kcX!߯c\.f/_ СF&y[o;e䩓FЁ// >+ bqO՟U?YxM/3;)9lѹ'r\'154(J(I IDATk^ּy@ M\cMM0L骔5UUUUZA>>)F&f:v>aChv)*;s Iå8\c9B(xiaSoe***2)]BCPC5y#0RL̘OùW*/IQd0˘HM;gv¡ß [qs9'jQqy~g?(..(J p8]be"KrΜ`F~B|,lc3e*tʮ T{@FQ%&_b㝿+UjT=ǹtP!"fżoN#4MQMKh121c  !$O:ur^]o{E̋~\_4%$.IC?͛U)kG;{pMꪹbq7Ӳd]Ov]v6rf>ا***y! ?@iuۮP$vVǸ~/Вؘc3;u"0ԬkD5a[^ze믋-+رwv .~6SBHcvq^r!$?HLtEQzz ())mےu޽wW=>bdd(}P_^~sǴKG:ٿo~CK$tOPK<4r43N}nv_|a@]YYYEYYWG')1:sK֌:t}G7ųgO/]+EbC*((xz/YNH\)+RVɣ_3dfUoo*3[?xq˖|U[ۯ~ TYx_>ÇyܽGwH1uĉSҙk1h؍c(gMfRq=oޭx!֭;g[320 kxE;W~\I,׋I^XB:d}zMӷnv%S>!?5TV!d!~DtEEݻvhcF8!׫[Yʶ-͞Nm]?c4y 3ZJIbxն2sC#7+nvX&6"J (py߸F+)Hŵ<,Z^{^O'ϗS*!$fnTXxڽ{u ˙3;;7*,;wfiݼeԛ+zhkdbQg311Ó'OE(+s\1a?Dxw, MSYܹ*2ZԔTgϯ-ۥt@#{Iގ;J$iǎ-YkwL,(*UTTPoA$ E\.9,URRAk(((uܹ 2pKͰٳ޻wޓW__OGmI.4/ v/ٍ yk A=Z?Xhc5Jibdb]@ v x/&**(3 á(PEQsw.nZdeV&~O0nJ;,6yKqö6}ﲱȾJڑ wE={`~`Jǩױ++u$E(TS#p8S"p8:z [ 46a~Pشsz? -^&Ⱥ.|9˾eVڴ_e+mߘZ>Wzo[b&'2#YXs8EqTUU8EqE"a21r8.!N7]H> ҍp:enX3wݦ!N;!|bCcΔ'J":F{6IENDB`aqualung-0.9beta11/doc/main.png0000644000175000001440000004164511107574203013323 00000000000000PNG  IHDR%2P|bKGD pHYs  tIME  IDATxwD*}D5ZAAAiiiQO"Gjjj_|RCjthhKĺyL]CCI*gˮܿeL߈ő>aOce_qc0I/>&K_Mמ11}1ɥ/KM1D<}5uU) 1YFå%24&/[]/AQ7Q2I̞cUg柰_JL:ʬ߄_߹u >/!8S6mԫ4lvaaϟLM͘D$樫[o8NuUY,b>pWn~l|H++PaW+Me%KEb+W%JW`d2TYF/DpIN/M\B%Pe̞}iJ 7Z)/}8KKKŻ~rb!vz2llFDt9WfQgC0:CĭqS*_( ₉*zV=To˼V1Z}odoݸ)o$b{ټukuP'.u Pe:}JI`}T{2PYcR >LWNn3ir `3(ˍoz`¾S$oMM}%-YL3cPp|#>ɩ/Bk6oӋQ}%gXvDäTL_ xiaLIR|%J%;}BUўhmսNmݼngA!qul7>&z3FZj |+"yt-uOFI vs&:pD9&+?5t3wˬoGtqsX({d"7__Q#I__UvB+KtCI|+"B3bΟf_s)9L2q͋_v߽|61&k j#lDw9"2 RG"ET~HqlE:܉ "dKGo_VO8G /?f֔LrQ  M45hs'n^ =ϫUqĸyQ/:!dwΌb~l Nduþ7.:g[F+cf\nt5P T{ȞQG p3&AB@oǒ3Gް\W7ELdw#:U@-W"] ܸrn- u%xAჭGTA&OW)WωXߔ SJ7L"D$st> 26|Hߨl(DFK[D/%eBpk>NݽۼO_vl>uzOߌg/|nw8:kVcpjќ˞ 6o_\F\$Ek>}0z{bLly޴g:S'mZhM.vuEڵΝ:˞Bwlܺ^l5iN+ZiG;/mg5CmfNqؼc_ƋWuj.6oߡ "@Ϯ&\96B%Ňw;,3_|(@-tT.,UK[sCdM|5[v]n4㹶֬)]vȾ=7yҢϛv<\cnńt8a0Z3'x,lBhUcٺ++fKKWoJSl~GylfM,%;o̗ZӜ/uw[=NOH^ի玓"c6_}!p{'\ltK 6esCϫɔ >{EKK+a "q_Gظ"ū%SKʇ ua$֩#7Q&NeMdvɞC'WSc9>o]"+rq0߃A/^kkiLma5tˮ/^mnh) {0}%`'HK[fl#l6u8MuXrpI#BGaSr$:8<:fdv(l0D[* it%ygȓQżU=}߽@8fm^`)(Xn{^BCƺxǝ *^>  :yM2#D`ƗB[|ş=N`rכw\.70{զ!}B~bO!3d?j/)(\;$,V}$&%LJ+_քv/K9q:yuSy<"e[M O^ѡ%!Ԩޓ"xa}=R2eiկX,붿*,,;Od=v!$nݹu⸨+T.445Gu''[wߵe5xY~O(..Dl.bxT RGJJKc8gA0u._7㴧ӞJOqUSc4=p¥#{>pOٱpVV6BxHa[|KF75)%1vo=xLMr xN/`r%NI,I3>#njq}m}!TXPS}y|԰iaqܨRʓLjY9? 44ɬiw4:om8uj}@xAaQJZzmD})wkB''~ʗoO֩}|g ft{O MyC uu KåұmF4kvpyƩISfRQk !@)ZZd1x'sK.(Mfd<'3Mx.HgOHL"" ϹswzӔ7]MΡH,a='}Oyuo[ׯ?)~<OOUfCKJ9"Ջ>Xuחo0 '1ayb{bdaX,b,ƕ n%=\o8ߺ-)-/w[6KKFרic·%k Jbj?YQU:ұDx^,JXF^`H;8vmwB~۵ڱlW3QAa$Χ7ܯWNm #hk$}I"u[CFL^ԷgmFyWW\*IFr)^~_q,&䐸şS1OܥUn}#z{UK/EG,7k)=ErWcf8O;Jܪg׈KUᅡ쥼bf-u4e*BO3_X(Y Cy+K,LLB! Ifݽx$}hU4Q#]!afj|ARiJV\vvզ|l%D$tK\E*mkK뷒m[xEdjToи!Y_g47(luy j)K'ʎ,_&e,°54<εדЀ]jB٫gB ܽęHԬ^_ijii:CFu"M,ZŔb?OoZ[:(,**{ yW>x/_mi~r* W\MGgAYA4үOk`m%%Z5#MM/W\9׸aðWoM <5GbDmMod/m`| Ά\zp¥~lE p_e! Sl0uu=zوaɰGj͚2_/m--m-.lZI#hjh57Xh6)JtO5'pݍsֻ.-ݘ54 X04S~,55S; SGKKGKsֻ6/{ä3+rޏnԴɲyčIc*QX0q#}:q#ų]7lMJ"^IFs&Zs8l S3]B%=L:VuNK S%sȬCF/lP6ka`35?}Ҷ9KJ烨Mnq2oֽ޹3;tX#c90p8f&Fs&y6mZ5ٖFgv4՛6n8w$RxȚ5sl enԱť, F͞`bT61l:e)RЮOVr{2HaTgC=߽O DrMUOKE<0-/F^(--IR6iRwSfGMc5K̛9ةfV|BRxl:yҹSq OMv<4H|U fM%(4bL_@Ъ3k0SɩKm8fY8e< =S< HvFqO#LiǾs͚)ӑsMOc1Kf/Y4wjZ5>z9֗*3&a BWfzu)(kK~M>uЇV{6'LӉƝp3Z5k)ř~XȊyӈhʿ*$2GQHH|g"Gۚ7/)-Iyvyĥ7ǜS`>MR>S r8&Ļu };3k.G|jY9/ϛ:bǾ#sMr`ilj̧ px&ZVӑf:T?|o}|4Z5>G\2a_0V'b8dٶS_)QوDoНWu5R̒:]4YkѼh?Z)"ѬÔз=%OhfhIRiV<%Pe?iR'*Zz-I7!$:12QY\Lwd0ʗ4/ ݧs棤;aдY.W߯{+C[[""YiǯҺHy[d?-uw;!7Ϡqӝ._FhO/Ӥ6wSg/~XLX[qӘF< AEG1 IdIJ88*bzͲmwL, 2Obi<o쟦z- ٨j}[/hW9S@M+׫/1Wn$m&-קIkdעٿ STrF|q%eo}?}z:ثU>xz?no*d>MV3O.W0Oq-L}\_rOO/ťO߿a:&]_e1,WsCY6k2UaC!K@P\mfd߰a,_  dFp8E9GTp 9Э"=CׯICxr޿}B3@ahlJ Q9FQ$v B$Bų'`@id`ҀD7 9…=z5ja@.H@ !㸺:GWWt̘Q}zrSL?8%%%G##^~jjfD6MYaS^ާ QFFUV*R*))aى/Vx*:v:ŋW{3[z^vw~y&-*:SXN f/^ pu1~ܘT@*R[\\<˗-9bB(t W=|t9yyBy!v:D[[S\T?m7aO$ߋQĝͨLJL蔜B3%[#WΆᘚx{m2dp3g 1Nl՞?4yJ6, 9…54676ҭ׊k~IMTHXo歇،p˧k>&fFٍKTXF`nֲUή_!/)s% IDAT -| MRlE?{|OMc&:tuӤժUVNgRF#ynܸ9nev-ۍpMV8ioYmF/+PP|*ð^0 >* ɫ99s.ԥG Ӗ7Qҽ > m&>J~~q7X,P ~=lNԬQCGGgŋ۰B3RLF8y\wsؖ?J"II04&\ҝ&營 sܘs)s?o޼y-n3sbc{{nM~xr%߿˦v3ƍ .!+&-yM0LJVxgb4ΟD fK=9b-B(22JdB ƍS,V|\LX5TCmW.XDOOոG:0_h$ngeڥU.;yu9c6HIw.t>w< m'f,^;@>а:1rUjj XY&͝3`5aJRmܰyf(Դ'*̤mU \#iFxfӤIcI&%"Eݾ~`钅uK/{/qr~n:˖.RdpB~/q SPZ8N:ul9ysס7O!~Vջt)ڵuBf&)i;jjjtuSz䲤\*1_FRzo߿G ;}а%%%!a Luuu=J޵KOO/%%u媵ժUk׶M=#9ʡy|xvjϛ(%5mcةXRgS#E ijc e튚 (\O45hMշPM"C$v $_/--c Ӗ"秺 vޱcǮn}z4 Qm.$VAEoS!aլQCvF|wo__p~Æ ڴifr?"ƏKeKKPRgO3BFr8/U(-}R"*]/Pi:!t6ds!!PfBxmanF)>g>u2==C[BTH(a WbA Wb1 ;R<[WI\2s*`&DN ݺuƮ^ݻg#Ǝs ac/cV?^xYŋ "T&;vh`cA?~#tib%(5{ Ƿns8Ϛ9QN8URRի+˭:!OrD(Ib⭷ovP_~Ν&޼8R\|~~BeK TQ,ׯ_W.1|`vRK2%*))E]ϜSRRr̗oڵmr*qE17n$.\0}llG_UXڹj֨1`Pv>*BE؟9|p<]{u+,yԗo*ݻ_ZRڧ^}yżCw/{嵵{>ZpRLܚ[>&9DxPBvv#E'KFB fΘq.ram,]a;t.oOޮ%9+pyIzA=yrBЉC>z,sFJ WT\ȸh%hndFn4k4b$XjLj246Wu3#ɱ"'#EvhߎY~ykf:|N9[7SSJKK׭߄>tܩqF}"~аȲKqF&ԓ$IOS2S)NO~oG̘TС6+WhvTqq^]#$?m|=~G=== 㦸8`qQacFY0!550ޱk-jj=;\V-8HCo?74#7 T={S8?G(R߀(`^︖w-!*^mqr T2`yyՖ-ZtuuKb<3M<15GdX͛7[n !BgϞmvv g͜6lPz""/[ICd^ԩ¯߾͙3۵ݽkGեvDᙈJ…;wy&tff% xb߼u{$䖚s;fΘ6jpy0/Ayck'Kbˢ1IN~4i2tɓOmD5$UEZz˫@d3f1b-ttt=J>`էYxIb>L+)) =|1B^{yjjڼ54[KqJ ?Iu{$;w6mjߞ-[zri'GE$:.F89gvq cbb 쯒DQx9KcmZj=~7֟C\;-I>ϝ\`FfGnjs8v$@5{B;TUB0WՑS|޿f;Gǎ:vXFl6{6n sڵڴijӦJ=yyV^oU'%r%ڑ@MM \܈f#񤼷 \TYqc|vJ 6c$GۡCB= jܨ_&d$!%to7B(2*z=Yo՛9cv \Tč|%ı1/U?~!7nuFy?ԮGS\$ڄ>xKԎyˢ%*B^[ma_FCrNҪkc.#>*V\\lo`б}x^ާEgo߳osCmGmۺAݺٝyݢXRRr&+!3:QYg͞'1z^Q޻iNJÇ B $Mˡx) * <|̺?L>k|w{`HJK{bLZ#VZO6ssvKoKqڶ122l߮ŋ%JCvʨϼHlBv[}CG,^PFcOl5|in}QFCҩS3f01رC&MK,5mmmo2jxrӖmW,["%` c}UqWYg7jq'w@mWAA'^琉Jz:*Bб@KgϚAI]'wћ& 1MqVZZڼq2Rg#؍B >44ah0NZˢֹSG]{N'C @~Fb!s\~>JF58O$jֵwTדAG̴[Wk֪J7wgb{ݤ$C_x9?5RIiCegգ9)S!aaQScz$L8|CG$f$DXtof˛ŋȇ7+/Ԡɮ{/Xyynݙ3w܅7oE0w2F?|eiǰeɌ. Y,PvvFX_F3⽇Uck^I֬as' 7o\xMe6$3uU,:uܶ+??_j^.N=?z\ZZxO3U#o$F^=q%o%9ߧ%f.L?yԱcuԑʪ'dggOGo/:/AK,嗚W`XK/|Ҟ;9r0Rv#ϝBNq^fKKK.]R*ԯWTTt?@\Si6av [覦&w&!fϚ>~bHHƌYsvt¿3"U}=~̜1{cwN~֪%9U`N&MtXw!_PXp윆 ̞OQu5{;ovenI'Yb@ ԥD*$]?Jo؃ x] @xv4jhh4aАaEEY3i!KK&~۸QM*V)!aC׮8i<ood7 ?˗.^de'qM KDf,gϞxزh8Lܩ㤉&: ֯[ PtءzZZԷK|z+=$vB߿IJ|*R\ڮ^ (ZZZgB7k*S9sP%9`@ 8As#3b}^<"C]Ч߿1`m[7jiY:~QbRW\8%u۷+))w]>^Pci(--]|)[3)qߨ)ZZ!'<4%%[rz>w/fɯXW/H<0>|g?Q1yHB*FD囑x˖':Yo&X,֦Hg b򭨶m[15rXЙӧ'x?wďV}-M;}&|[O.*h3kX?lP[o+o+^9rĬUr{ Brc8N?I;ܼy^e! ?{ndwGb:wOi %B&{~SagD޳ٳNԷR]ajjRV-jCpnR}={9BO^8$>/HDy3S٢iHnjXOJ`@ekäZjl{sǠ!~AK.7p ZVfi\IjmW|qЧC%D *P}m)DM~(׭[sfPiDF0D!m VFtDhߡT5c=ni bB]6/JoHڅIC`4ZB(Pxb(7T T&e%u|0PJU7USN@ʆwo046@e DD ѩ)_鉜W 9PJC+xkck3lmVSVMGaLmnI^î]wATbJ@jPiKwXs?4lLTYS ̧ ߈-≟PFeT-'Azs.@_/^ԭU.8%z2q7.PL ߸jTGn`_qI\nٔ˽}{yӺ}6&M25n Tӫs]0%B6)h$޼M޾}WON5m yg%P"D3=6f>4jl}of7o%|Anւs\eMs0ek5E2M6x!DGkCB]'BQ3 n~]_ MZe̴5F _~7@UBt}Zȉ@0 $ wX1  P*y-! @%oM%ā# P8#o77$-`s aC=L#kԨF=Ccs5*`WOknd1 P.[] *TܗUHlTn1N*LLMA*$wJeʩ@ gh2鋧B;}|G}d"Y m[:;6exwNn ةV_;3?d4 (2#6W1sN#/ӯ ?biaey%y2UyWRҽ]3cn^n'K SeK3&~0􌏹4,-,tueFTHlT(rHgpR:uԩ`永TYK)Ө?aP(^fuʸqEsq%P/^Lv2(#2 Qبиܘv!a))i׭aZ!/ۻg70jm>YosM}^\\bbl8nXIj 4rfjb| !®b)O&%%݃*av俄QUzZ>L#<֬8quPJjZTT̚+J-d@ @ 0 Lw862:V^9cBϟ9>ν Qـ∍ %Æ nRR ɱu!!6fě6lMMM]l6[koq8|n'>=j֨a[ZoXxl6{`9+$% {Ѫ[IP1QKKKcbW "dddCmtPx):߫Ӧ?!::- b?¥(&?DWedfVIȴu֖uiOݺuZ$Ϗֿ_ﴧo8x\{h7j8oδJ7 h67o޿lB+ 8P &b. IgCKτDԴ蘨pG֭Z67)3ݗ*rfݺtD]Р}fo\mr?*3o޼6ZTަ-WKKRlrTMAAҥ+wx֫Wos- 9!W"M DG9cQ&-K._]˩^k48ij`@Ucc1MvmmlXm&SȱSX- W.Wd&C_W  q^~e߆aKM (9} p)rIDAT&g:ulInda߈g#2oSML@ Xa3#E}%?OʹV~坍`"g ּY3 ߿g꼩7#WQ޵ as0[0CvBr͸~zʏl)* lƍ'lЃ4g--`&97IENDB`aqualung-0.9beta11/doc/playlist.png0000644000175000001440000012567011107574203014241 00000000000000PNG  IHDR!y@m IDATxy{~bˑxWO^˯"""Mxd6Į_";(S>]xJm^Zmll$fq/z߮WRz`3g54 3 :Nof]:BoiinAv=}$ rB!P]]]KKKC}-rG XY%@ Ca#PDDvb Y(²MeKOhhzO!mA^QQ@"WTDg/E>H ""Bc~(3L`3=3%y!b/܄׊QpK ȍx$:Qcx_+*""c8WG~5=dm/Ÿd>i/O{)+=d3NϻC& Ng0l#?RUUC.d=qp}}ϟƏWs!%%%[c D"H"I$H ׹Hz< qC5xLe/HnZ{^1^ѫ}{bao&c˵fdMOю^N MsStҶ`0{wl4vv~AgҎ!1GxjFD5 9f;1毶Kh7f/1^^&WR<ޟJr)T1i7H$X.bms98K`{qչ<0D$: ^MlK{Bg񻣖9a™3"2_19D$?S3^S|}G8u-{1 2ZЫ?~κ~kW|Rccϗ- HP{Qy?Dַ.%8;>qA^ⴷf/VmdޟHMtz m`^`}_.˜]y t ٖ{ HB½zb{b@^׹HzB{MH\kz|Zr8Ej/F|B!j\D"qԈW, ]-5%.{YN!N1]؋f䔏}mkz||/{W3 ڋ}me1! 2ED"DP!aaa d" #g\=$wreTa G]]]SSuĘ2cuL}2QQ461u=ye_f'OBvKݿqsD)MDDDJUΚjH%a{G.tDKBK]M4i:͜ü\LO&>/15-znSȍ Ka2$_|u.yec/{q*?h/n{iuuu;vw򿮾N#\$G]hؑy^8szq]]ɿp;>њe.mO>;3~W^^&`_!íh7ٽ+mB XxGOg4LxI9`;?j#B68{oN&';nw4f4ߥno1Ƅp毠D"[>AP{xxK$_a2_-=zj!`Lf["M+;m3~+kIC^(^cpc؋đÆv]~v> @Xlܲ`x"x W| 0&""ݸx7x|b{qp{'Wx {=_K8|ht:ipuA[Bȅlj2 iۼ2s}1כ,sy;27G$nߎ^ЁyeE"/S>{wdֆH6ty^L&@${Ԩu+` Pe&hN_|to* JU|"?2"s9;/V0{A̳"9^"c:`d1B$논)_xv?wd} 1g^^ٶr-vm/>Ln}e<_*  ?vۺ  dіTW%JcO_T>}x$n{ɳH{H$O`b/WGt"/#(h/g;`6GZ1^ؚBNSfOΕgݑx & &ƵL:՛wVgɸ2d3ELɳ>75l^QWQzT܌/so0y?`XO1{=k_n2W-}edD"H[{:._3K;^hk}uVl1L di*nF9_/@0X `_WBg0|LPKZǰ^`.ԟ>+?mӦch2W}e+7AyTl/zL7Ce⭼o6ZlX,Eb Z\;}N;e_w¾2Wm}e?si҂; )x ^P<-$19c`_+qH/y|;Y^+}eZ_*\<{ O;=c<&MW/?A^+}eA_V>s_:c2W{!#s-;֡{8B7r,:x6 m~S*z j`ryG%1}K^lylzSbk.^-"Fpً:VGz*||[&C{\K W/YPOGcge"_?f0h :d{!L!L厢Pk;0`zazݫ@ .z:@ "z@ ]11@ B:10.=SU ?/HH̹ j7Hg ~%GPjW36!C v  0@ @ 1\@zN} S묌lzn;Re!CzpqRl zkݫ+$C~' n?Ԛ=X;򕧛6ߺ|TKIIўRp(p߾H$RII=k((*{hEZTTD~XW#1=uv6)$ѓ'/3_9}76܊s6)2CIGS}[;`@/U?W;T6H_p ulrdQ}~km{78P`Z3 9PR[{NC"Vyz|y=G人/m#F~?xc FBbbsG644f3LY.f.sg•>} iۭi6@5GkaziT>Y ׶NLT:xGO*=ټegٽ?}}3gd_zpb'J=PLIy ehOϞWz!r z<ggGSǭ6můVˋbgVU} 9(bhznca̟hҨ?XYZ(+O5rT噳rX/k+^Fv߽)|<[SC~onn{͂%'O,b7Aȶ/?&-w? "u5GSCu2/?N+Lׯ]&%^zɪXToʰJ<R C_ܼ{jE>7x ;7UqgւKǁL&{=4hV=}@E|*-=}F8 un@:#)hb\/8$FW|ڈDjjjB!ح JQgLOK ?N=7bO-^NlqwZ]ƭSt[ݟL޽)W㑃3gC\Wrs]poO>uw< |9@,3#f~y9fR_p"a4K>#?TwCYc6kFT̾>/^G爉~߻ׯ%LsQ#Nojj&:6^kdx*7'Lg]r_9c%?XbxBډyNܼiZOtt>\\9s1ۦ+8T1FViC60>Ð#FrH>==cwDD{ *=TEEk9HB,L& PMc?eo߾-.>Qg~hfaڅ?/sM!C,Bϳ2w[)s\ЛmtxzJyrk!2H7L^j@UeQ\.p>4u^XԮ^xvmWŖ+/Wi _ꨪUf܂VPygtqg)=W۟)tTyV7nA.gcR9Q ?"J1 ̬k1[?]c<o͜˝=‚|pHSَep>kWC " wfUtI,w~@ 0CwcY)_۷/16WX"Vzq=c @xQ|t0ر 0;h"HŘc5 tMr sz 8OyStS:QEeSt733{XlHUAwMqDEjj&O熼2ؖmbbmbbu2WH~~:MM#ɆsvQ_.555/df ii =m3ƎՀ纟`ߤT{ŝ%SOOͼc ŃKSE&&^^UOO:㴴#rd2cQQilmmnPǏTj:kuWGPRR=22TEeBi5k68@EE pL1b(Bvܳ`\innkã[CC[YYÇDEEzB& HϚ5=5u?HHHFkCN5k-7͗((hܱ#9k/=EEϟkP )) ((h-,))OO06TPж\K~U=>sΜ%:jj&VH%|^.;f``0yYyPUCUU_AA&##nDf@x̪3O>gh8Շku+-((YbY~~zB=օSSOY((L628~ l87w<#@a((GڻwX/aa!Cdg%')pz)>>H||#^Y~~UZZd2YKK}*$.M/_߸qfB?hii&-=D"IKYURRG1:˧PVVˇN|ik. yz\p=I֭!!n<]d..^ͺ{7kԨaa˗%%))166ptLOHH)) W%%7CꆼkTV"mOOx4###QQa""B80}[7}/]ʣsabkyZ<ʺgOBddhi;6S߿xüys޿픕ݟ4IHK8>k.`d_eCC S uvã6/iӫo޼}ɻwMع=Վ:=eb.1`׮xGG֖k1#dVW;mvK~~QII:FUR_Ȫ\aa)[PP5覦'O^~+//PP}uuw>ʎ=Jm@/|1jԈ_~A]^`xyi(Xa󔙛wxyWML߯x!kgGUu"4ܻjjmĹ:  an&ѵ1%K&p Ȫoos#Gjjj|Y.n /B l:k ^j/[$((޽{*8#77СCnw%qqq]&((~ssKi}yzz:&"$I]]#jjm]vv KK[oU1ۮ|eݢ0*J- [lI9` SfgǏZ''Zkn{8:tTg#~cg0&&J-њ☘x;eϟ;aqu)((ihhњ?~;? sg)JƏ[d ^mRm11B -rj Bm5pېݜX]dVVbHxmj:V8x"tF JKšwo(~={5giiC?jWz`'[xWW>ɧ?´w˸Ϟm}5/Ϸ HO@FVXε` SF& :[F=}e)55唔8^gy#~6 ի7Ç \?($$$FG--O ѣGZYҎ_Z~ZYq3rgOEȃ33OAW@ W~_Cs^> o߾phΞZ{e6||_xRQ?tmH::Zo޼4hy6'H`iifii@: W@ c c @ p<M+KY|a ~1xZYs11@ 0@ c "tDa6ACVNݳ !?,ƌM;m+/\ܳ0Q8*O )JJ)(Ȣ)=vFff6zsCo{$33ZAA:+:z;KTRҝ48 "wuF 焅=W`mꍮj 夦77tFT "bۅtiiii:Q͛mk,MA%24mf<==RAAr/U9s(*ꨪ껻c]m/ݐF/ ~`OxpX禦f}eBUsGGUU}m ,UT< 1?}T55%+V,o-ESSOY((L628~ l8cr˹s~z=BJ6'Nx18{|܅o߾1ͨ'ѽȈMP(;ӧHЕUdUII)?O%)eg%񃖖fI$ U%%m}&%1EHH…'O n PVv'O$sq_tnݻYF@W\|-)iOIIgzzFBBLII.(O \[Rr#;;]\\}GW7v6?`wi /fdd8p$**VDDȁGP&׽u+fpKWy4b.,^l 6gk|V={"#CKKoرiÜb'O(/ǻw͛}uMW(+kvb0mٔ{{z?%UHKE\\\Zz/N>3U0нvƌfUؿy=noB8,/,,K1SL\\̥SXŌdVW;mڔ5`eKА!2aaiiS.[-7.*aÆ P(6߿ i-..W0uu2YXR߆ on`H`C^j:䫬D& +++1wU\connˣΜi07u]88U AA9%Lt1) +#G>|"+;ZTTt,(h2YXUubPobb*\/cqGsl }$I?ZɽH*(c' CsKKZ9%% 7lX{ d|yA?~̙l׮%K۱!'kSudXߞFn߿p\[$")_|M°aC qq1]/ƌnKHon`H`lcExڏUih(Ux̙J::҃852'ߪOGO44tT-((n۱-<3~zСYW/KN.N 54a$+aB˭[BC#oc>|`0|x^xE!݃.0]CqًKQv>..p2kK62A#Qd$ud`݂Sup=rݩiǛCt,Zbg`ߚFYD"͝;0rDRRdo-e:_{)zF}aMԤu%;0@ ) ϚWވ&$$`=r֠+Wn:{l&׳JJWްy( A;H>EEeݢ2^0t5o[ͽ6={L/LwKtssՙK8qMU_P_pɩ'f#GHI9TY4 $n /BN^j/[$((޽{*8#77СCnw%hL=w6AAee[JKcӉާ6iH$uuu- /-mWiĸoqx4_ag0&&J-њ☘x;ȩ۷O8-& Թ444h??~%U 1Box%K曙+-&f_PVVrpENmaCȶm`$n>>n>>Lfee!ڦ3jꏃ/Ba`k ..,{6 ׳TKKh{zQz߇Ճ89- «vuٸ-[KK=:zΝml-,L߾}7x&޷]c.k_sjjkB_z3|u**JȩUQn&.*ާOoN!ύ[Zz@G2 mfΞ𗉐y{gf)Ǝ`2pߟ$0E)44'˘ ȊmHXS+˖VV'#u0!mh9:zyvР;8@@ c ,`_@`;p3*tBϲNĀ181ћ6DC x @`@ 1@ c c +A/cr:ki_M[x칓d%E^~2`C1?߄ Ӧ^…]L2_*qUҟ StS:QEeSt733{XlHU8\]Wf_XZfcm. I^^2+E45& G-cbbbmbbuOmTVVV夦77tFT! n --#87-B'ӹy3-((A%24mf<==RAAr/U9s(*ꨪ껻K7K:^'\ 8v,\AasSSO.2깣MFFW**ZYPQUg ϟ>}psk)YbY~~[{POONM=mdd03:4`lsKg-7o沵<i3f;~c'f0+!oPYY wÆN zgtPM&iJ ʸ:{ƈ9 ~p85pIi9ĩzuHN7i:X9~@$-=gUIIUdUII)pAtp2z$77?--ɓ[y11CB6:y2ɓv#\\ݽun֨Q#/_KJSRcll虞SR;/זNo}Ս-})xVK328VZz+""#X ޺QZz38ҥ<1/X[5exy>+= vشaN'k?hhh|ݻy+`GDZ\\\s8 㸺Wg'˙KJm5g]1cxE6o޼,]r4NoiiIN9t)(:8x|{ a}aa)[p۽g/`2 ]Wpzem![=%t $d2?EG6m ڎ:eʔC+tk)d;..a˖@ee%aa!Cd#.]:)""һ[n]T BPlҶ[\\Ưza*dd V߾X懎'>t(9(WYYLVVV c őbc,qܒG9`n>++ZssK߿ppp>**sJ8Q+,,QSSRWWF<|DVv )XPz dĠ Tq_|89湓{i@T>毟ZZKfff]Ϲ9zHY1\/~WTĨ#v^CBD99M]]ܐ?O4hǏѝ6t{ԨεE.!! Kkk$ 6cE^lb̘趄D 6?6VgOxQ2*J]] [YX̜i)-=S\##}2Y񭺺JNN4l?zDCMMM5!}}݂ɓZZTjQ^^O=cd4Iݽk.`eWWJLYybS-فiՋFEFŠl?x丼cSlѷ~GDdFb.N 54ػes[>}6? h g['LX肾"~zС0tbVYY`0^xukThh=|#۞d" `0HH_OOg˖@I~ cXn=R lttuq(;ꍸHcc#cxy'zzڮkTjqH$~-]9/AX]ͫmQ1e'Nމ_{*&,_&666B:ӌ6vC6N5Ԥ=lذݱQlBKKD^kEK~P=|ذo,9 pHѣGndh89"%տ!2b N=`f6Y%%WoXY<} P^Q>EEeݢ2ʎo0J-kmPE p_lcL7y| mUDu#5Y~Ɛk4pEKK!C9ӣ [0ۍ|x.LnUU'޺p%{WMmbƹ.%K&p Ȫoosz5r䈔SMMMOº?{mРEh_vS1v˖- w޽p% 4Zϟ>11Tj1L-#1 ~-Y2l^m11B -rj Bm5pېݜsX]dVVbHxmj:V8x"t JKšwo(~={L4 *&&F?~Ԯ^C2NNK1>7zިGGݹmꭅiCC۷qq=ۄklG[iohl`be{KK`VV涶SjjkB_z3|u**J]j-%c*?(?ws~`Vo2ϭxT21NNu_ؑ8+G 2Na )LWv[7sb5{w |#,,,5PZwڌ&q?w̹Y`2Gw-o_y.c=Ck:_jP ΞpYd:Xse9Y\mk,y?[W/z9-tJ>߾֠ yװaKϫ241G[i"C &iga |'@ 7~# W(hJ* W?܉WR8 HB )-۱/@ }+]ϫR!B%#wTÐ/_w{\JF)Q[0-57%v\^h]_ݐR[f޵s,νy9(5PZ*Xr꥚OzK0ۇ׷?l֜* @: ; K#u; -k=(%rUMmtWUS-qwwՎM iwo^}IJ!'p_$7^IHHx`uhLbD5- EDL{iA*'p2b`i]Wt}¼",,,WrwYݎ 6?`\V7?--h*+G(686ZȰxxJžQ&jQZo8~)oszg^O5ךOR]I_j>x.SEII7G |3!C۾kI.&d޽yu &Zϒ A6D{656m}:/%o-/,,7~jIS *ڗҏ[PoΚSkl:8|;v<0okl"C< C (_hpa2Ywڌ~Rq;7kNKoc"71k}|`N.޻U~jZۏdXuU7"jaH`2^?u zԈ%e谀5? \>KͧϞ()ƥ'*ʋ'Oũ0;~k+}%j>}(m˚OtdxO54zv̸9h6{#Qd qww 8~iaJFn/1qH}]ӂY߾HK9G^Qdcƥ81|5&or7o4w:09y?ZzVp@)N,)ț9 -)ȓWTcۗ/+ϟ:*"ڋ׌ۅ+wlZO&S4+ϝ<50x̳'MX:.bs;H$"?\E NΫyT4zkhOyR wٯMMi&8M{׹4ǯ&pb9m+Ie{wngUl:|'n&!dD?QfY,jh«?JY}Ǔnb0r,!VߤQR,,ݿ+$nQak>}d29pr-5l M"}x_$]$6]9&lW¿+jX.^q!]޴/!U"Tx5xҾ'D1l=*A^Icݞo_K8/M:%@zV%d6o0;{~dw!U.C 5$ .@ c c # ӉN8 c EOg{4B`@ 5u%B ?/^8޻w F .##=d gx=~Q#G&%3z4W~DϺo"k5'K?͚igҷoᅲ22>^mm rqDru쥐;bSluu 7;w 6,vW$-7nnp̧ϟU5J WUtD1Y-bՄiP m&Sc H>| |^?uZ_foYq?* qPU>g3PStu x&,rS:ڣGjȈ7/eK/(,Fk0.-ʋ:_k+Wm YzA8y4F;y*ׯGbk9jv1ws]IPVk]r-)=_LP\WrͻvS;vF1 &goO2m/?jWTNxk;"bbx{B$!6\κNtt#Mþ~[LSC@¡6;[GUٿrϪ W1ې o}m؈1oܾm &J}% m ;w!c<ƦѲ.^ v@]}%&NP⥭БnVGG@8;L։wFlUbf>w cC"η,\0D$*Ov!&\mv ],§ )XHfW^Kll ]EEɩFc5LO3t;{sJowSI`.o)] ٠PIf҃£*qVWT43.Eڻw^BKhk 7jjb$$4^H{N&llD =Rx7R TjK]SZhh(֫w.Ο[]͈uWf߾)S$||z|$ȐH計wiQQ >Rb'^<Qi M1Nu.]U+***%cfF9rcch>O``۷>%%/555A_~ј˖x)^P NرR$d7*~43%%Ӂ/f <=N(+ t?)=^^:8z֯ T*hX ^Tjd2AFdbB9z7LLl@_r (3{eKZJl{h^Rhc4YBlַ]inڈl3f^3cB,ysϜs=Gy{JJ-==8ɩM]ivphkn&#Ο23ԼjW]K|QRj^fCݸѽfW YCy޶ 5(gv`Ff&1 , !$Ĺd Oz7oȋzvnׯGV f%k޺=ر0FG>xнnW 77~$;?\Cxe#B?ͤOS͹|ٳ'={CB45U  [}Omyy=/Nzr*Ac:q %%BM"wߺ77wJn$DݻS& ]֝8Ho!NXI%فŘC ;%'uZ7+22BO¹o7ÇBXLtcl& %'O*.f޺Eܲw7Ymﮓ'HLqh ENj= T*۱pa_lE7 tTTOd #92=0JJa1N2ՉNHVVw}=y6rXDc45;;{T+,,APҼy\}':x99.f@֮mݷקixyML  ;;ބnrj`0qp)).8<=n@gxzNpr˅pq)+8!ڶ70}͚޹W>>54P))qpA7v,̦hKb'!5 :4j72gtc0)+sOﴰaPMMNfœ93g&( `k^5w4Tc#e/-Xfʆ֬->:'g | ٺuCz!;ngٜωֵBDBT*AT7%%vxDOA7]];EintO$فżҥth'BURjz0uc!\ᅦ߹#A-orr7obX'?C ضkucAj`oaP?K{ 03A|?}A,)4aɒH{v`]h).&ݰb5BU55՞?C&S\a 6/_+,xt]!c09GJY)?hjMS.=dċ'%$tnlAV`%KЧOw2Ҩ" @\LDE{]9ѿKYI ,)aL6̕Nto+} ACN"Q?~$gfvo A֭8;GDߺA<}JܹGZ绺)UU=8\ϿCMLiaYHٿ[nL&Sȇ/ZN8yIvӧ=3g~\7&}{|"H%{{3x֖[F!::Y-[xrD-/':ԁTEfe"̾+\\ڊIT"ZQAv-eݴ>Ԕ{m-L8njٽh_k=GU*7?Ħ׈Z s&ĕ811;S(]PP?QQop~gAԗ/YH`''ތv'dخu,++'Ih4#0Bi$!uTW8wdÙ6ԩ}Qh em7deV<=O>};kqcʯ*ht$v{;=C8ں:2<Df6[X]EtQ۳/[#95=6&z֮ `LMB[wT*P, `_h!=]"Q S ݹsolI) 3+WF =ԓcuuԴt" D"1*:ILe( UWV.㏝H:i'3q(zfoO@>>F(h 4^_> d?scsi ^x~'>>1}}鳈..;z7/9|h||*S:::SS]<\wEEEnܸfжB<_ fMܹs?:x]]LWW'3ENDbTkn}:w`>fP[L~mHH4z0nV.++yyٴcӧO{ÉVV.OUTFm-}2k?Ξ=KEe~VV{ IDATș707<@xQQeeE?9s?f׿ Q#+V~ʕV :** =[Z V gXa%/cjWM %##Q/%嬾2 n߾GEeU[n޼;lKKk -.]{PWt9s$CCh4DHVRRԩ h jj@m]cFe#ʞ]zt[kj`arLMsg] t47V ,[fv\EMk{Yp`MM2 HC B>SP65[VRZ6ؔ#"cԖYX2SJFAWGEf yN30_荛L͖͓SZhhze$ YmܐzASS Fkj8eFfXnY\\\g :%Eoc JLLb=ʲ߿* 4\rr&>9.VV9z4q@it\VYYZ…997 ǁ޷og3>ݝ' nβLmGfiin߾՛ɱee.1 RQY::nϿwYQ8X Q|H{51azzHy9pXܑ !_¢GRn {?F__9*-}ưrpplZocԔhn!!A}yy%!!!9$(rss͘1-8ʕ,p @__W64|055@1Ÿ0vt`y`4=kuE tҵW~·<<<[ھ}t´O۷/jkkN(;77giFz Cwt733y=R\\9Z`Nnokj~$%Rbqq }a-޽ hߞǎS(*ˑa.g߾U ;?7 bbMMH;L&?Vb̝+O##N;M&~n֢EI'S@}hGDT Dw9 <+={`]FEE٬&PAAvǎ11!Wǟ,1IIKIXtyrB;xFXx*''gE+nuىh1a#g@!=C..T&ޮop`Sv9TTrr"32./]j:X!>fxp͛w;::;::<)ܱc ߓ[I̙3~D;mB>-"IAI۶m˛7o}|֓H=okF`aZDRrVF7̒ fn222L;N dz%%oݸ]ج0?$i#RPPX|LųG2--lJZ<]ܺqu$>7+-/+̜1c >~ϫg\t1yy8XXXJ$ Kccmlz_qqzSӶm}?aڹRBXD.ce#f\\Xll/B`0#$zCBB2P HDv4~~gccls7gϞ`#/8;vi177 pT04 ;***booLJ3LDR١Yd!^lr6,b=IHb=W/6vs󯭭[4==FV ?R^^p䧕kCC `e27eN\g c| `dsX,`_ݎ=e?c#Ï" Cc>1D%ߓ_8d @Ǩxwy-o}^\RݍQc(gs/$%|P(i8eeWoruu 3]] N>}]\\dĉ-áĤ1pM"xEo_;D㏲gx|xTT|DEEml'##m`."2sRR ceilJ^^xՅ v}RR/р {TTkZͻpGGWee{=- .ȸ ޿byDD\OORwVRPQQYwVX.$$F555N&MMmv)(-+)-C⏫i-ֿ{we1j{ ~ڍ565440L4~ݚok*@V5 /_ze_|Qڊ ̓SBBZ`lzASS Fkj8e Vȅ VEPb.ee~jsĴ#GBND WUVApnNMq`۽%GGW[MwΞ=+88{x9rhnh`jj( A[}"| ^h9m)g\<ٳ'$$f! !!X99f̘jWW'86**XJj6ABB>> qafeiYٛ7 ('7,O/_888v:𘙙Df8KFGl30 ;wN2P[ÞJ͸pZPXy$K1fQQTLL>666` 46^8`:w&dCUU.XF~՜ٳ%͛׬ZQCbtļO L@+*^YZZ6ܹ}c'O0uk >Or% BQԟ'N'!;T*$!<Ԍc DF ,1ņ ZUULPjjBCPo7V6}:uty˗o>q"wu?_޽+SU>olbL ZPp),*urv88uww}HjG7w/TS҉DbrJjX>>^dE]I1lo3T6V)SNlB'DSC#d2Db-al!,< 9QDd*Ôbmm9{,d<i9iaaɼyR+(ر5&&ʕpmrrrVTM`ZRR72@EE٬lЊF37oUQ30zqlL!<]Wp!7dSЦmlnYl%<3$0`f8*PSSFS#:! U -0jQQQy櫪*1LّI"h2bc; w1LioJUUJ>yR8s 8\RrVF͛5?_>-ضm.߾}ߴi A{8chA<%lRR hE 1h@ǰBgKJ޺q>pwm?|,쨨5NQJjNFFo߾;8hŅ&) hoo 5sPU{׿z"l޼6..@䐕qww^Ԕ-cbМ9k֬^?X!\0WZMǏ9_Diiu* v$f\H —}k뗹)IG9Ekb`>L!?F^>m00,2р11>c|  /?Ɔ$$t,_iho}8:n?o?|VvN&׮\l?\KJFAJFaRU%e_[[5ھ! Z[4BiBnpg!춰la޽nڨvJdd%+޺ͬ%c'j<"jg%PT$t c~|N)*?XXH:Q/_ At7+2@3BQjrRaaԳEų}}Ld? dٔɓ!z__?JPF_\,P{y9 yF=yrbqPH@ff7փͨqcRS;%$8hI8 xN$pRh}k~mki=JJk:|i:'6u Zr tyǓ';w ax9%ĤS@77CzF< ̓SB":ip8϶v;M͖1T{媺lmfh r6㼍:;?xQdve+"=ɉOCFshhN$$hI`-n"n,N (.:|X 1ƍ>}TEEB}>,.b'df߽֭Srs%%Qw_K߿~z#e/Y0^y 5f]ϣ>x(. pP]]Y A!ZipAbEyY?C $_W -)9wG9=zx9sfφ ,5Uii)u5{e/_\?FOz|o&n̴{mQTlmqvn#HlF[SSCF1=sߟF9'=G h!!NOO'OzM@16F pJJ11 ~}sDHJv!]S:v`rߍ-7o}]lAaÎ" 4y2ggg7nY50_u}Hf&sgFg5/_JŋK﩯_h/g-Γ)..Q񬤼JP2 A  ܇p ݠyS'WT.r:Z565=}Zg}O766r++cr)#R\@i`JJrHH;K;?I]wX',lbTTQHJ8Ay{ 81iLΜekRRdnߞRQ13!(_JJWrr#ߐ۷{D"i??HKSC#d2͝6MݬĤJmhh #[[>|PUȈ#---p>Wkڵ-WŽź]9onfr&=YPPp s465>QDD83&gP$$WPЄ7()q֒5|̒%hd^?Ҩ" [E+(pGFNxqRB"˞;xQ/^ik&u4E˗=ff\cC`\xپ=ξJjvpN'=IL*WE}=rq1f(f%Vql 2VDDf,Z,[*)9keի,W@Zvu(^^ޑ$qGTQ;**\t1WzOlԸ1oߒWWHԶ6JNѱC-[xrD-/':Աu-/Aio<}3sf},,An$]ݔm$0[\0…);,.Y0Yry_߿w{J8pue%{\}`/fT~,^lVSV˱z?/}k@PPX|LųG2--?PFF}q/GB~_~99Gʹ=vH$RǎuZ[ц7 L&Skjzh_e"9] HnJ^㻽=߀Q#ĨxLKtT׾}(h4B,r%oW{,,xie{DWy9 չcb76R pP?QQoppπ$ u`z9$`̡;kHHp80靋?{Z}޼!O±lϾ}ƍǎuprBqϏ"j@8J˿zQ6UUfiiu* v$f.fXo\inEJFWc>_G%oܼc@>z67۬~ +z8XQԱ6> _?OUT0&vALv QHII301Uf55,,c#"T} bcۚkW/k3Kg@|Iq..](f wDyw {r >,{W6k]X{ddNCrro/w~~~i< #H`qqILmǎJ7f cjjL$clfg_a)>ݩ|y{E˙3f@&**Jq0սEU IDAT!Ў&<<<P(cξk1 _0 ýTS҉DbrJ`cGf}fnHKM~dC} ;;1Lp/;4id6.TvڽWxmX~,ZbiiT3u̲ef˖ vM^ /UVWRRt)v%$%W,ϼXax;wGGkdff76~}ׯSL#**NCVPPr􅂂vqq1..' Wֵ|  I$ W8~]hCRR…6mZ3~ʞQQA QVV s|WψLmj|DŋɃj"#m` IJJ߽#==ah \~gJ+Ξ--_W1a%=m%&%Q(px]]ᥤ_&#A'@x8#RkʕVgff3{oRRzKW>_14\!/ebbyܟQ 5axu`sqqTCњj..iipԫWxxP(qq1O=_WV V@=+>&11 (+˾_466 )/Ϲt)ѣڻƍLvS~g BR\VYYD޽G..Gڼy:7UU߀ӕ,4gͦVӛ7o=yttt0sދW܏FNJK{}#>}jP(?6FDę1[TVvv1"T*sLEFQQRR!g` OHH @4cƴ`U:#SVV>}"| ^h9UD;ϜxgOHHdeZyrYزe[ &HI9yc0a0vvjϟEEES11Ѧfޙۭ?_̙ 0 ]]yy{x/L͝+y̝+O<>xeii ;dAM#b5{mG Ο?% 0ue@X+OW.3 М(* ;i t~]ANԔ4S1cZC#oy]PF/Yb",< 1UU .44:(HxA>~5} BܛCCEE)'ƍ|UU%.1x H$ ܽy1{8chA<%lRR $ROss <55v.)9+#kY:|Zڱm\}%`f,X7ăU!Ҝ!!;>̠8;;+pd!YYׯ+#\~{F%..^sH.&GQff||gΜ^_.( ~88߶JII,**bCvP(Teeuhh#j1ctt4bc|} Qf:UPNNjE7X|XQQQ{{k<>uRRs22lmwaY7};JVU< 9-6X^|efmm\\Ofki_hFFb=IHb=c #"b7mUHh. l޼6..@䐕qwwF-֯9N Tpp@sHYz^ѯ0yⵛߝ;)~>;1ԹO&w ̥;&&[SS?~~Ak֬6CGGGs޽]v`| `xXbj `〱2czq󖖎| 0Iu )UQ%Hz8XQUUe`j10O**`dֳ 鳭9eSe%eK(WQZ^BR)i׬(+YnSCC05p*8e~~>>,Dr~aH|-/+ǀc9yweyzB-Ͼkɞ}ncKFGl30 >}(**:`:xo Bce8@_/<"Çn^CN$S44ԁaޮopggǨ= סbv 2d %""ljy_ 0? c@+aY^>Bfǀ!iQd1yΝ$$f:QƐok}]\\dĉSUU\UUœ?b!ߐʞzz&*X!`?cFFׯ{@{oʴR?_H71d2Z_߃zzZH`BBrHQ1cZpߕ+}@o FVVVἒFs +`5xyy'Nps۝?@o]h4z֬?fQQTLLa> ;(iiu ]ŏ#h> OqrZQv0SW[OCCJvr͝+O>޽P&O4(sپ脄`)`%FXxjccӌOED2LYXXbe@O''98##+RPMHHK;w RTfʰ_;xFXx*''gE+v$ginnGv?^-$ ٞh1cڂׯ߁Oq<|8ͻOرI./ z vr1CLLq322.wwwWUfG;mB>-"I%)G!66cc KDRaaillfڞ ;B܋:;DRE+77-GTQ^ن q6 HGG3..,66OP0E{{k$WW?L&mbc8u.fvw666QԪP>,쨨5>##'$$_11ݻD?o}^\RݍQc|m >@ w3XOee _2&8P͙#f k#z9_ΕSm{ʷ|nkTꛪt-,-W_F@@@(OLJ>0>fs`@.fk,`3nk뗹)IG9돔X caBBBh4ZSSq0%7zg`$=Owoظeekc g+V*ϒk` /Y>>w3oՕ/(Jqq"8mM͵ TWW=s:)޻,;;'88;0P qafeiYٛ7Kavhhxm]L}˝wق¢#ah2cqԩB&Ʀ&֯5Xd!M$q01 ]>cM߈S%;q$HaD~~"LF{vueӥkI=1x` QѱϞsqqaD~8]}Caaawޯй3f\wؚ &e+g3ӆXm(X_ccCf`P(TtdABKJQ`(7DODX/~ 3zgq#3((f 9M!!'eTd %**xNQ噾}鳈..;ÇLJbh:~\Ν..^p隕AΝ$$f:͂w$$$ߺuFIIݻ-3Q#9UUxɘqбX9:;ھ#rҎ}r|ԨB=}[N.^XX<}Zh` ~{~7}w`aږO <};kBXDscdd33"dd4s46^%/el…hibb)/ed?J~ʕV :** =[Z QgXa%/cӃt?3}ګVmynO:=gdh(VRR斔 JJJ:uo) ]Q th.**۹ӮBTW説lcoX$5TsqqHK]!9+!1VP Qx(q>-r%MDDWo&&EE˾xj|˗/S%(Dd-0,E&;dS1P|̏c%c| o>Ta` HaT*-?w2 `>3| Q*4 e*e+Uhv7 Tq_93"H$n\tu^|տt5_#n[cXi |mmjc/ƾ2S!q9,r X-E[))k(W]N=eϝ8}{'5-yEM>x=:hVNo.B~"y cKQqrzVb3TW莇[w2F)-_l>7\.X:J <|8%9PZk}S2L7{dIٳ%c hsfoejh5`YO ynٲI>^׮ݠPw7~䢦r-Bi}.G󯀝QR9ԍYֿqwhYYϞW8d9r굳gϝLL|q) ܑ?zٯ$׬(+YnSCCIJWGaLq&O3C4s ĕRV]@&h')SOϢ/utlzRNǂ>|dtg+V*ϒk`+VX$_7m.t7z0277qt~,!~WNA\ k+']YD"q;{`4> *:M|Z ee ;DZ⃗,6?=`uې11?ңё<<< 'x0;44L&j Ky)xON CY(PPXy$7 A6g'7 AкB0%Shv&?>斓Rz\pvV) )Ҏ@ՕqBDd48_ڲ͛CrxAw^/h u o.,%1QGxxx;>?_9G>DY؀kX(II&%0?+~n\MG[ki{Ϙ>][kA5د`lQ񬤼SN|ts0ͥ !8u#r,I[ pKޙEqquCDq3Xf5UJm9;xQѸb&ř x$M<@<"0-"UTY1!0Gde}ax~{d=gee#!Ĵkk+Rr⊋KYl~YyDGW\@}DoEx/9Hz-]>%d^|Id[l1e3aj$[U,Rٳ-4/,CPH'zK̎D M'0s/zUUUNKQ5 "liy ZZFEE"vͫv]FP}52{'%J!g,s\ۃ9/^JKM&5shH328Z^>Eqf^u=I#~SC)H5ZS])!-.NgLpiۆ1Ffiu,@(]5 GnuLD=i8|W"-|zO!ƟXkim@#ǐ[p֞t@pBpj%2`l1D#ZA2!9 8K`d2WZ+1t0y7-i rbΕcr 9yQ$%+WJvy70Jŵ}{qyھb4NSKf3u΁w܆9S[Z3m]X[[9 1$''8yamFxxǹv]冨~8}2Pb[zrQX'#PO=z8wKMysM:}_8e:`OJ46ԜD}ДƋy"IH *WgbegD? ^fgK̙+W>!+/2 4*3擋$ )5lXzDZf]\.7~?]W_AKKn1[B#‚A)=IaQqrr֡!UϔU@n-B.+Lo1!Y/)nj333b:mؤeE ӷ槟].-.˽}:hcätNB9յ RG^yieQVa奅 w13DC(ߵ͛ee6!p>}+yEYmѭmEҽYϟI߽ <ǎ>*.l~Dԅ^5 m3U&9~sӳg?GmnScrT^Zr!LLL?>kCo?<,טWlDʑ4ѡ/=ot7^1^&x!gՕ;W 2U0A| čIENDB`aqualung-0.9beta11/doc/settings.png0000644000175000001440000007410311107574203014232 00000000000000PNG  IHDRkGNhbKGD pHYs  tIME.$ IDATxuWx8wq%$$ądnfnK2so&;#$'C+~4MiR'<:UZkk۶!C,AmYYY>yL`{H2@p䋝?}p;qŗndР&aqf{nzFj*|>ڐAXNCH5% l=O➻}N/Qr7#c#M퐑%DtI2CE%Q  LpUF)-+,a?ʌة7蟒8 !ZibY ˠ "YaFXXOi.[jў~VUe))TRSC+M%9ɀ'MieaYQDT3"$2Oc!hjjtvB4;aVZ[c6oہ%*}ɛ4IQo)o6hD521M 2XHP$LI`h:HH Xj=|)1h@-_~'d7[oE8t4Maa P9CPnlM547in' N/  ӝ导ңX:zqβjHIss3Pbzmp; X'Mdѷ íLRTp|HO$L B7-Ic pTSO0&Gu4"dfdPC7hnj2M ƍ}V`M6o!+20PS MͲ a1,As [$lLt7ImcuYz,ȧ|W)HCAdn?0}T;4i"Ǐwc_=gsU4J.I@3 @ MHwd{$66P1=,ٝbI>?p>pԡ,2[&Ha!ü7iX$[AjRJt2a@ydlqYVdE)eP"Ih.m9M67!LfdXX4f(H&ON,]ydI IRt#Lyu9Mush4Dy a!!$QHu#/MN*ahRn>PIINBeniIhFDt$Yr:yܤ$yHyINEUUڭJ`$Ir( "Q M0M!jl"Á(ȲAN{-LB 2,t:͵xx3r2&9?X6X]]C<Ƃ_SYYaĈ9̘1?dg =͚9x$kuqqݵWQPra3xy]w2tF@xW~Q 2fʆ~O=,SAC(.)+fĨq :.ڃRvvWk 9Y=~}u/]'%K+/bwuԑ/W^˻{,n!K>{P{VYZlp[EQ:dY۶`aG'6TSSÉ'f[Yt)B!FȦ o~INN>5 1Yxa9jAI.dH–`RѯLKKܜv=ն v:oV\? 7 :FO:8IK^xexJJJu@ ;/bt]g-\Íw~HӉ餤嶃[۬_MxxG8󨭫#)Ǩ#y'ZK7Iοbݻ7W_ys?Aٵ7%_ȇ}|bܶbۋ`v4nk܁tueޫ ڪtKٕjвZ g.e57@queo6_Yc:mڌ#5>6~mۖReYh̪Ūv=_?[9]6+GXfm.6Y]`ٝw ,[* l ej$RͥA)Pۤp+͈>>~ޡeM2l V lZ6IJvΐ^^4M1e̬IYd$)l:\ a}떎!! WQ)FHrXiq41 21 e0Z:n* #O6R큳X-AVh iF~SaT,.=P^~o9[GJbj)W-L ,36QQ^۝[w.X͞k7ؾ+DqTa, @5f}FtXΌ;k,?1_Ӧ0 ٰaH]ա=%kgeEfV*eAAF:ym>d4mcpA,ZݗH VZȑc2,dO^ZœťD4YI̢DD4 RR DlqGk;ATUV#/Uv˾l=˃hWa۶cÚ`YX>8]4u 4&doE* A~e7lVfJ8Rc٥-(2Q]ͼGqT2R oi؝Dݘ} ӉC&"1evcӎ*z#Xv֏[bS ")1Xxhj Q^^π4JӗYWM$CQbu>,D^ Ivؓ q3%K6з4Y:J膅$y^fOKV>39},]ӿq8qy7ha{;ttvVy{Hfס[).]N6|ߟeɘqc:lh˫(c4$IHv/m S8fB;w?^E;^3o eG%E%Lݛ+8do,ad.~FT"1J`YX%N#lZvײpr3}R%gxV'xŲg2uԘD X I͇H,:{f<%)&'I&3i6R[v'vS(IHiv )ݴht%˲01EBc4̃C[jmjDIK,mUwNشac;8ן۶voDTXޚ&e%diѽ ~̋?a<';vyݾXj+0 7ɮeZޯB~@ u$%BFiK>lk֮n=ęsG!~]$VDL N8'\EKLZXGt` :%$F>>͆hm2TEvjQmæOMk?(ܱe_%]44d*`)wjcgANN67t]q0׾ok1`M9}B@YM|f]w-#Gf l+*Ա &JJ),*w-4uo-I(JhL[9iDXu'cQf "'+ `ϵW\ͅ7dDg#ڰ|UY I@0LzZ*YYb;7tE8Xr=r _Kܮ%Z?F6l I$Cz0uHeY!"TՁp*2`ÆQLfZ=DdnRLcsυ"ɨd"0: tJ)cXv=o.昣渣bbT+L$&++QSd7_vemE445C),EQQ {@4t`԰33vh_ڀeL,SG4SRٰa#NS@aa|2dYr3c)F7 |Ł妴-{K֪;:d(陬ڰ,=pdw4 2ihj$%!}{* BvQX\FfZ2g͙#).*!%%zmAzdt(,,w E0:dOiE-ͽU뷁e k$-QCH#P^QMbo!е(sҩ'P8L}Pގi 9lťc~veqa'[U^U'E1 &wohxg!>iƐ?e-[O8#8n,. qcY&evʫy5.jڦF?CFԈte1chvs F"6}2c /-'; ףYU4e&22)?M[f > Y,DX&Q=JVF*>7zz0~!2iVYC$sӍcݶ2ahX" $aJ555y4ekoqacP<γfB!ˈebh:NG,d9gK%vD5:5[ilnˤOc0bDXd${HOKˤҷO/_C:~6+-G]mN%)BpQGɧlQUHTQ3Ͽĉ0bz0zӻ{7+BZtˡOgebvvIA~7 àOA.Y΢Xv#iD5 DD< `biЧG;vtR?l,>՛v?044ѨF|> {Y2MQd&ȋ (_AnH*ѿ{6i>#!D !4]|X=TX2,ڢbB)L%?''yXI  !/+=铟MVz YYq:# x IDATC(~{kkQQ]Ϫ;3vLL66PX|v8'̌KWMrr nUuNn7Yd3x`?ͮZ.7Zꚣܰcr1ǰmg1hr$5ك&cg^_} |{MNNSZV΢dY" ME,^?-ۋXn3yY$-`yذy ݳSlm=RPR^C}S=+hh IId&+o﮾@ˡ2Xwv妡Jn(oldvPR by{g3?Ҳ,\&O e{d"A( #MzJ6>/*{0e VᷙCQHKNfPd=r EQee؃i$TTKڗ>s(g,Y LZJ>&/{Q <HKKgPI,yIG{IPI.+Zt4q s٣y Ͳ,.,i~l@^|ESSSfA̚yZ\`DOYN%KWem^x~3?;[-deezz^|Vl,YMҒf~,^}ݸ^{]N?m~UفT/8]ygs>c.o>mu\r9 2))L?t2q]!rq 8yDѸy8+8ӁX'y9g_p ~OOa7uYasZOSS3S'OAz_G=055s<6lL$٧zݻ23ϿBm]=<Oϻ}ոs7mɧ+m;x p/85Y$N=xW_9ӟhϾXW\DVf>+.>oF39̋8w<:i;_oҹUW\ȗ ;K.F/Zqssfg^?#gKoQXm@-7\<.{eQR7~︗;n}z# + E5"a`:ik>n 0cvM5]fT}d!qWf(ouh?58fpƌE躎i;p8qHh!t !@SmG] БPu,V*r%fсm;v,%bYVh1dt2SE8 ePĠliY(fleY-Ule]ؾjpUL|(Q-Czfn:n`hQ4]#  j t 3fL]wà^6+~`bd2d@ϒ #,ԴVaO1cJIb$'-0MC ˲+gK~l< 1,3M<0 -=NZ:a^blK+ظˊ "0pp0H0 Ca k_i݇H(7%bbt3Le+fn"!%7q QME鍖҆n{2h0f9Î<>hDcǖ‹/tv`߾b6+ iVonҫo_*v#IYUh9ګbؑ b9Gca|<!,a E+$箄@cd" I)/+CQEVp8hAFFG9Ů ul;aFsJ$dIBVd$IAcۊT(Xwp2Ӊ("!xVB5^N̬,BZT!Iw:\!Dc5"gv#b`Yi׋"۷GBV&[An̘:>.2,รh'avIq!?v1?Ӳ8)gC dQ֏d]cVP} cYlcF `1,[C{{԰XRǵnr!6lpfF0 %vnj7z8i"rv[22v0 DQd;+*-2weMu|bDl]`%PڝC[n6cG'e~>ą\sq،[,[990e+!7'!@+#?8[G;۪vrBdr\ۛ~}{zxW[^߿9+#L?$ĩ)\y\Ν{{Jfw~M*#t ;ʒ㲷%\4T=yw)/$5%)sYsHJj_𬡱'|v,qİYzZ2nx3j8_sYWnbRYeM x۶yO/83ZHeUX -YG0!.n3GG\m 2$h$1U[#G ca?K_Ngu%YVgKutP]`%*PԽbVڮ 6hGjpy0*&[#Q*&r/sѕ'd`Wl0Qi|Xh{W S ,{ĚQѠ<^VUc{VA椻6j:J 8YGӵ?Ӵ4)N5) ?/$\hS`bY^D&aEi fm%Y&hlX g6Aq,R\b: ahq H_u mV5˴) 65Ȣ-_2| J`xV7p3q$'# +m0\5{-8e\}g64Cyd'w(}Ӵ=$_l}V?j$Iݫi;8 L X y}[LR\ )k4a}tl}m쌮i* dAm X:,Ȫ6w&ǔEXQYj@ݶR׀V0tLE9o2S<*DtAO1dF]̽}ra?eBdAfT7>=ٵЦeaA -7 9 YVgjV6〈fz{Fu #Sj>OC)?~S(),!-"M$a+FOOG1=l%Y)nACBPZÙ0L4.EjP[σ˩"d䓎fCEk0 UoVy8ۅ|vPb+'JK]b!h$<+=fkT˲Є%߶HF=hF'3smRUEhg|RVs'f"X/ZcpSG$~Y%4-CJA" G5\{ȄMK;;$pmWuO))S| mH' r7*z~w#ߍWS#$RV9NC?1wl$}o|\ߞ$PKhkaMaB%?6'mc?V& A%]6Kom+BRv8?W]~!,sMSp8ڝM;ښ7g^⢹gsur~ӯ}>lwy 2Oe|| i||t.~w@(ڂ+Vpyy%Nfv'|67r; n_UU͙]F o\r}+o]ygs>c.o~׸ev>r~ޯeΩ'Q\\ sNw>h5M>eΩ'l*|>N>8Xg4YŁ[vgk/^|<׳ul^x}78zcQ60yoh^=uKxܓSSS/]ͷkSf{ ƻ -7ooopH? Z{tg&O_u s8|nn9[si-8lziSؼeSNMZq`< l^He&l sg1'~N_cΩp M]}][WOܜ}ÛoQGLg!fYEyE%(۷lÇ I߯YCY{8|8s}\zy6#@p~=\v3C094a,> O=6mW۩"?[p_iWTƩw?6|>03uĨL9sɼƻ>7z/2x^JsggYhÁpPQQ}>ul^=9s6}_تn1>{8mwhOy13y#[ /PcbJ!U]U˿}[v'3OSb2yR(J,E,JT$T$IRRQFfg'`Wy>+rE; rr`?,p7]}`oue/ع`dU v`Wń_j 7u2b ڟoj=vVW{.qX6./a]~VA?-ըk:? M͸NR%yHM񒗝$DI4+!,m|iY9 0C$';f?nfl*bˆd%$+xf\5x}>olb Ɍ˱G[x={(r"ɔ?IS T^С8U5R,3v_IP 4#L.FAxW⻵5uBQZRSq: #m ۘ8qUe1'3:l8iE5$aPte/<{|^}m% @Ut@`PSNKKv0l K+ E ~(_|}~};m@ 9) ҅OYo :}yӑ$J*<|WvSm&Xf8N‘(+ࢋ.bGI׮߯$;/{QVZ#dIj\j3V(ڍ y|93y{XNAC49 %zsQlY$ 8蕗@E$Y\wh ]X7o8ɲ'hl3 y7@֬\ʦ 9 03dwanUgܢ^F00I .I6uf&RH$P1:T8qӋQ׽Fyq0X""MrLEMr@2w,.w>J8R\Z+/2qL%FVnQmnneM![n9TFnU(Pjhk!IU1LVþLڰQD*¦:@,Yf|ͻ۰Xf,O4oսeG[ҹa J?hm;d7;&6ځ;(S@,A"م0VǜlP4 zp9|*rXEQ2͵lپOvqh<,+yt`#i6$Չ8BAגĺv3o1d*%'e$qqywtX,QV,sR`P2qT*Ԝ}]>I=HtaD##1MDZ2{=y1d]̚/v!(j5fSY[ 6nA:Վ?],Sص m-/Y줙.d Kps(.gO˲Z'4k䁗7p|\@"ѤNy̪.

    m}#J<`4W,ph f۪6 я|S8wGoRQ6$0m~8fU@0 02wãLW()Yln<1.>O{ v͏@3,45q8<)YƎkU xFOI!PeP,Zբ*hzxi>st%n%9x}H D,ʂ:5O@ChjDuIV p8;e>_^}c+3ݝ;e.OXIK\Y/^ͷ}rO+?qTh$fc9pM ~C$W]yO?SN>!3-E?U3]y%8|߼VNGC~6i:fL;ߺ_:Jq}ʅ`5?#:أ> sN&ev6nB(No3/Rs7n~جV'sT.H KC<C)'px.o3cC8NGG1aj/ZD 0\n2OUP U#+l<*7 e08PVSVLȇ8fB= @i`? CM C%R 4abyI >̼K:hjP^\ƮZ BmkIuq*Yc[ظ٧ą.F2DOȪ*t}Ml޾W^L[(VP+`]4try3stm{JB`C!8l=nΛ{:Oo{dbDU%55c9 wa0Hb'xέhLwW! t!d !@ A< u<LJ2u 3O:#GsN|}Z<7vYR a|6fO"oG}NA, a  !#a O>>˞^Cd .S&M0C>мAsk6 :`[Z@V$$EJ%de$YμOo v%KrBsk˯}T*e&|3@7^D$F4ARҀAIGA<Rg^z/\s fQd ]vSLe[`mBi{W/AP (B$S:)!0.ВL;8=?upv vOU*Hh$Ҳ2OIII 7bKVf ܔ4:9D(@F 2`p ǣSR^͞#*+;qxSnlu…]EQ8sٹk'x"6l`ܘQ1 AƎjCKi(II$u$IFl${CX#v%/> 2?]vD" à`0.s939x٥?B: b K0 'YR 酄aCV%^zU.8x\:F5\t 믽Ʀ?fԩTTupM\qŌ2}mT')AYAd) ꚑ NvŸUYzl֔1r\v;w\5:qisYz53Oz9Ih:$/򬔮r8BL7$BU% r]YDAyorٯض{;a`X2~?],ߵY Mf%"JBG(Ȓ/a2EQb,[Fwu3d4i%>L.>,f-Dnv/fjˆoyR?bE ){QT 55uMYr`wkYp!QS2 P\P{T$3Hi*rlmYBQ8 M26dJK'#w| Ͻ/!VURƗdǦHŢ I"4$XTZ-f  ?z x<:$.=EAC]#\݊0Į5XX5/EFAH-[GUyQ>8,I,-b[8ciN" \.; GAmkQ,ԑt),p#'H c^C!!in駘+뻊ļx4 EQ\IJ2"+ 1`]3D- #5_E# ,652UU;W8?Vz){xȂ% aZ* ͂E-xvH X"f8'b|u3'ΛhB. #yͿ1}d**q@ *Dt 6RB3)BA<B5-2;TtXM~-?m̙=jߟ.7F1/'X,*6@‘ʀ*I23dTMJﳵiΙŢգlLfcy\ysTTK).,DO(aH,HjP-b-m*ƌ(YQ>W`qk%E7k&5v8yHA2;m;ve7gsU*5 LW14زy#.;h ȲaV {)&ak&_Xĝw| u̥:x5ɑ OZt9 .׃bavącO<=| Cޟ%S)~q,XxWfy~&s\._|$# ;D~f<:vg~æAk˸ XpꛟC*GXBGg>|/z7c'~?b`_H;<YYΘ;inn9k p7+dG~! ք.^π_ym`Kbo5PUm]]s ?Yp}c__gMw[2d#<ẫZ(B{W`^kpWr|Y`b 켋QgGÊ Lj e 4X*? 'e++lسͣ02ݰ Q=MÊ ?As0L`?)nX1|tm ;%0Xݼ᯿lpÿqw;G߳V0̭}-]|].% ǃ #>B2"MEAf͚EAAn{пn8FAAӧO7sgؼLjٴ+/p8=Zp8vmX2z4M7ߠ>{k8sH&lܸ˗ͩ'#J\v2'&̘6x<lKig:z5۲ /﹭V+&Ta͚Z&NAuuS~?7XBj¢fF˴K0{ql$V*J(ffqgx駟ac5vV̕> .$djƏC#1vmfp֜$P$ Mr\{|^z|.-[…s͞j 1jd5`P(p`XhlLDEfJ\N;m-7ҴyjzOs1oތ| ӳ:1c ljFFZ9(=N;1#8inZ (z%M7ois V(]׳ٟ$I xvt-SKft;$IUBee~z맔eO ShSbRyL'2nX,.wB؅W^5W]u׾+MW8y rƛz Ij6B*iqW0n$ΞtvYy~N-:q"kw6{2NL䐲,e@YeEQZlX%Xl6FVW{oSNrP]="FIQQ^n7_qq16Á:`׳|7mTWVd=Ȱxپ&ł.?>aڝ>n&ۙR3YpZ8Xd2ngO}='&6aZy457jֻEaQs#I-DcqE%|/cxkFVƨQc W! p_ᠨQ#F`QUjk7WV4ghĜUZT \|n'gʒB1t`m̘\W+Y M7ۘ kU ᠣpb_dMY%(Ďڝl6EmV e ]7Xy;[kwE8=bK;}k6#eU3C^TX8&Ke $I.cŇ:eRֻz*MhNskM-$sO͞*َK,0)fjzu8@u6ar/Y)y8"d_Q)Y%!x<, K_yIYL5 9r-㍷aBx bXZ'vVuP8F\Ew8!(Ja͙'MlV(I\U*/a! I'iIDAT˜` 0X`S'§ݯn3O֯~Aȍf4X§OA0ťͫsu?I ~ GZ]P ~_m;n4RW8"Ͻ2Uf>~3iS&߿l,Ê &.ZD}-*.ՇMf1i87hJȲҷ\NCA0 )àfᆛF<@4 à:l6ݎjraH2gi߃Hw;p;6g!'NwVgnΚf…=C$ -s˰X,kh+Wccq+t;(TF صug9WAm" =־,5OpqM@  1ZeV@2Ō% "k>Bnjaʕlڸ)3 5.*+DڛR\Z]G(1cytܳ0~VW,۠s =,]Д`V+ 46'd ‘n‘n¨'`9H%R8*usn|9$E% HtGÙ+t묮 sD+nRde iJD qO(DUSK{W-ˮclA ncn1VB G"#F6OgnҴH5[A,3v,V7"S9f#ƧtCM3 ݐijFvRZ1Cִd2LWG]IUvdzY2X0Q:;(]B"c(P H)]G "6K2l;M"jS7X+Eat`MRHجhRd*XRâ誂j99u!Ҁi+>\JG#ѭ4ۊaDd)A{ AAIY)53g-,$L!Y-2ad D& wzD>,L`\x +8^dtN2aCxVkOh t7|\% eJdYFUJJkhiކbu Ih\z4!ɵt]CU1Yh4fl)x}cÖ݊JPV6r2=!3g]揗a H$rG -4TՇ*uٶOa.맿e"B$Kͤ edʿh#2eKb1s"&L ",dBp8Hiʭ:A [٫/<شDJφƔh/l;(Zp&Hh&r9QUپ~Ɇi]j#"I4irnԎC$5x,Nu6-c_=ih)pX-$:Ɏ:λ"tC7K6( Yv̴6PZLh2޲sO7~,(>4Npr0rFL- _Np{$IT1goϻFZG6qM"'H  u FQt Z؋[9TIݞ=x.xVȕeQh JuPJ' 7Vs5WH&I85QU]*T78l5ޞ?> %Zڻ(yhnmGH.1I ;** FYiBłnG^xϘd ԧʋhO-`ŶQ]YLKkXd43"23_aޓmxK}eß Μe|E6SVrԤ w~Yĺݱ2Jz<  >jnWᤓgfE?M즁o决J-݂Ҳrlr͛R['mS`8ib!ɧgc^`U%.>@Dgws#c:)'}8NLr1vf >±bj޸ϥ0{.]ΟaϿ/?+7;sΞ@ `=cH:<a Gi86qc-_AsuϿx1yٗbj_g1_sk<XxSN>oq+N#n^|N|A39!4_-bΩ'>PlZ̋6?ɜs~o̐Y*UW)..nhܵgX߸˔t:ʍ_d9r|Ρsg  smN\*EEOuC9feA!2~!S\\ds~mV~`.۟%=DcS3=u:gq=!Zp}bxqz:sNf ]]]#G04 ] !x4nC@V$ƟpFkWIi:/}Ee"@B7WkZ=w:X0 0t #=C0Hӭ &rR6؊pKĈbUL&14f =VPb20 HӨ=r$U%54 X+ f| a ô!h(*Db 'Y) v%Jk&fyQy$Khz70Y0tjQU@0ҁMMp9$D"´_?O3'XrYAxWqB۾ٖ 9(:n"V%3,e@E5/I_|`X` XCV5#hf.NF#GH$٬RPVY';0y6}z0;edVƻ+ֲyN"26x< F㴷9u,G'ߠbጓf0sxڻtuhil"(*R\hds||G_FV3iTsᕏfsCpS{V?)g3/WKgYm4 W^[ƭ7ȫ-;#iI?s ƚqr>ZN<0]՛J,gq7njZÏqf4Mg֌|[dz¡3iOO; kE }v*?}m^r! .>_}>oC'@ǟ|w/ /g<0ՕÿY3cp\kYncRO8cSWxv~? ;0kC\rx_>yYtvrlPJ[n珏>]u>ۡz¡3BGge>Xyᳩ`$I?rnnno՚ʊB_F`ۇR2|Kx,N'X+019 ijn϶Xyw59@= 5xogq `~咃 }(%D2jbʯ~89xw/(.h᥼ҟ1k#Op•|` 0sοx܅Cmd]=;E?H1Nasv{>[`k C`r* CJ0C?vrp:tvquIENDB`aqualung-0.9beta11/doc/store.png0000644000175000001440000024300011107574203013520 00000000000000PNG  IHDRdHbKGD pHYs  tIME   IDATxy\T3;*n}soQCq%~.䂨)nX[*k*2(`Y"@{ޯ׼9-ԔTl,~euQ!jڠԢd'aNBis?knaFiftrbG>g??+Ls?9)Ms%J4{dt7Q=*&G?cQ48g:~frO?G7czT0Ub4&==]JKK>cYzz:fffkǰ,~eUlYQ!j@J%J2_B|2r0׾S<ۘL'CR뻁Q?Z ϐL'S+ΈI35=s;]6pTɳt=[kpKlm 1` VzZ΋ EX(rR) Nc$j#7VLL4?O(:(5g뿱PNV711!%CVH$_~#Fl| R֯[6<Du^dE6wJb+Q%TeW*lX]z4d]ng+L-*33NQ$=|Dd)n܆:2_kQdj3~LoRsz )K{Wk "B9Mj?}s4t-`\ڱe "+#SSj[3b07Tw?b.]fMuBφ}w)]32p0Im?D-;gLB`i5x4A??C|L?忡vLJLk07Tl7Nšf]8}Mf[:ʥ?8WA◈ڋO-g.9=}&":O'|j-gL9 Z/!#jW4z/jFv 罖:/ujUY̖=VޏOWu޹wa&&D3Q4iuƹwO*V(o-!u#maU-ҦJ865ݻٱ{?߯ T9Nof<1}+55]v,S3Ɩ^L20~X'}s46rMdjCR;ݿ6/V?w ީS*Xz3Z_yMa[ŢD 3Թ7<2}~uO~ 9rc2W Zgf-i'}Ϝ*hZ[rM%dj~|]k/|X:~29P)+gח2Wfqƪr  GqL{K𙿄cOB]O7mKV1k G#9y,gs'Ze^]0g=\ރu, b?~&gl3l4wϟLT_=XQNx ̟3˯naۦ'vQHn,LMĄ}3ޮZ5,E-߸Wq1bNš:](NDDfg6=tȘXZ7oJ:5_(WMΚωSgPz5NMEvzeWk41ڪS( 4MeL?>"ҊZv Erk335~,ӏ>VmĹwOP*Xo *M?j>Ku(i٬ _ ď?̚u[L?jmg !'޻OȞ=\fL;.L}eCLYIݸwA c~, E2_CI_ϼ9%Ԋ5\NvUL'?(>177GžN?>JNK 5eZ2.7=r -fpI?.Фa}zq#\x7oChx$~kt~1)WM {8^{SǍvk7mgќ35SqxǹwwƻP*8~Ucqز!(_Z͞VjZeײ}mfM_"by,~|ӏ')?ꫛ~}ZE:Ux #Od˺vzm~G"=eKvG:CL!n?:.Ow>~Ǐe~T*<}6>2X3^_OOoGUx4\SKд4oMPjڋ5SS(QZV|5寕,ie>c(W#l ?;01}7=RM~'}133ӻcZZZtrx8 QTTf:/BݿGZZ?+exwzFq?y~Zb |tK]q߿ORRRZJ=zARѶɜ j+o2gm l)l"jkju(a'C iמ Kckz_ Kt,4WKu&iOញ 3?t?|d-3Oohht Rx~[%J P@Q0 Wx$J$A^uJ#J JejZ+AxyEࡣ$* F\i 5 YgK7]o;CΝ$/[AgL>xaT(2lODMaOxyGAADMADA^=z/)"USYW4vP4r"K[(κu>P()_udr?0 ([ 66=h׮}ݾZ ehٻׯʕ?9v6Z Ofj 4_/͏?.%&&3qh?NRY5Y ԩ^i6RRR(Y$)))lڴcBBO^AQse3gr<(gjju$NNny ZC;ܲ%5kѵkg--ѹs:wm;J;̝-M:ma|q\h4[Bܹ|X֯߂kiB]֭!,\_M:t@~kvE{F5ChժPLhղ9={7ܽ7%A*CR̛-e z A>ϷӃ 8xSUVsi߾ -Zse9!Oݻ _=ʕ+r֬Y̦Mlv(&ݻ~ۆ)..# ;*g #n\s DЊiw Ց }>F @||"uηڶZ[nfߏ{6vٲ@ƏI/oɄ y/?t&LI XZchr9A <d6gެY>߂VXh.5+y䭷*СC:vl[oU`ܺurw\Yy,=Lԩ89A^e6''|M9fβbbb?G6q ʪV6mNJJ*׮]^nz49CAWi0,,, ԡgLgժ̝mlX#l*1ln' DU+]r~ qFP`bbBZZɘ.z!*g&DY+akkMdd^3g_PQZbQK *h={~soɓ=pܾwl=~ӧ0zdvK>n9\'zPjeZҥ+Z':knSbյ?gq-n޼~yJ%gqMnݺ?J#\L"F1%L0:uڵ"8xNNCu?.Wl Hֵ\Ere& `2> A>{?;YnZ5f̘kk+ q/'{vx{OgѢio]7A=oZjΊ~,Zdcc dI .$41x(Ѱ 1CB'Mc :׮r?ԶѵSV;   & "j  & "j       & "j  & ECSVVMtЋ/ADrɭЄ-ԩ8ZB̢EϰuQ 8CS}Y[7u3fL e'|yU077ťwS]+WSv*UJ篿  4lʌFc"WcIKKL Z5۶dJf͚]}LR^^SؼyN@fxv6l `0/3:5k%,mсuw>hgڵk}~IJz|L"MiҤaw͚rUtK*mY>czή>Tn{B4kDf͚hT\_lҲ;v SqI^ "qiS7o E/SS#qwM dwmYO9l۶3¢FILzի׾gkk͐!,X0͛װh S-Yx:'33SlmYė`V5{8%""Zر-Za ZjKYt53h><؉/1y'ݻ8t0#k,]\FNRC0>DG"%%S̘1W~TRf͚-L9 &)!II9|X͐!2W?<<|yw2 yB--tARZU֮]p2l`m|ܽ{/7\k^m Xx.]JEÆ ^_͒%+>Je}#-zPGxcNտ\nnڵ ;z?}~ <? <ٓt_צsܻwѣ'su*WĐ!7A Fhc8t`/z~bc0v~u%_5%t7]Ťs8pڱƵܹltԵՎs@nhqq%RSS9},S㏻I`A'8:::?[oUOO# Vի zu@ASAC "ӏ   sB E&dj       Vjg ŗ;BcjjJժ۷9P'2hQ#"HHTVYtiA35:''< *X2mtؓ|@ݶУ,Z3h4lmqwBll…\75jС+>>EVVP DU5BArei߾5'tR\rٳP̛ha}#L4sƖW[A9ejM ZJ2oTY%$DDдTR o ˗(ٷo+l/ =wz:*UСYgĉXz,Z4P.o{'3f86lo}uGΝ{ĉ0m[Kv;weF m+ <'Q P#u} Eд6kFa„QT`e9&LFaѢz) FR%[2q,}7Lqc;T*3ԩܹ6l0VV077=_->}2e\E t֙ygA yBܛ5kݸqO'P߾cc;V2Steqqԭ[GW񽖨N]pYݻt}zu9u*}]fj884ՙ+亯i+ 0S,l ,-4A.o#.^ĉqsRWNYu: Э[g,-# \ǰac_ B!dj0,,, 㼖Zsx 4h`ٳ ԯ_O/>W/>>1 shǎEgYh̙j IDAT'?;*Rj|ݓ)p=Y67 VA(LMKa !APǍ7u6s,DP0bސ!q-n޼_{cǺR&*))?=2dؽwgA;سn9J *@ٲox趂  IYb!kםm+2ot^֭?χxd6m ֚/K->|9s֚ӥK_ڵkΈ.l۶Swd„tڙ fo:~C Ghc8t`/;a5%t7]Ťs8pڱƵܹltԵՎ)SA5AADMADAADMx(4%.   >&C "jPX{=N\^}dQAQA5AAxN55G djZ)^8#ZVh–r>Slm[ШQ[ zY^Τ:Z8V2e)("jF>–qʟuw0xAA?խYoӦoO "j9S`a[*jժ=+ZTfziڶmɊ~zu'NͲeܾo6 W|3ݾ}sllӢ _M;vFY52FbcӜP2MtЃzӾ}w6mڞƍh߾;5Co~ܾή5-ffTR /l, jժ9޽Q(<;uW\Sv.] ;,Z4PG2axxL hiԨ3fLԳsOhaKbXwŽگ!1?,jju$k֬'(h)%JX}<>[~ڝ:u=;ԭkUSZon݂#GO>NV:9}BNL;tӒ}Lm\xWQ4j+n}zq<0^q-vf&Mt vvquWu̙m[ЦMKf͚w= ٹ7K$:$*Mxq E>&&&̜nڶN 6=uqǘ1SϿT-ws~ؑ{3j$]A:tӦĉ0{*յcǺ3nT΄c$BAhc8t`/kBʪ‹>`UL>s nKo\ʝ;PF׾N][+<.   ԣ "j       & "j«BSBVB "j  & /IHd|~[^r{h(8رf-hҎ /<5''B{ZĄѦ#_}5 KrFHNN& BBvqғ砽-}yT*Pc8wJ|/2|8}_EcbZǹ0㳀ŋgӸ]DG=)"j>P~yIMM?fժ>k6lXiT?ZCo#NfE-4.^Ӧywj k`MN~رSg ~/*u5zנʳ®>Ч"MMM^*&&6V Zx{Oʪ*^m[bA>PV f͚ƾ}]t7km [nٸqw^tЃMfС[ {>;wq/wn>Ʀ9-Z|?퉉qqIFmiN ٭VVMu-vuh*Аxu s:Ν@˖IN~W$5ȿޑQJ984y.–OӦ }.[hh4nn_1p焇=ԪU/wƒ%+7o&11zlY`n az> `۶_skϞ\t!CscSLCCdbbظq5,XTWgĈyv:Btt(|3_~٣A%$D^Ef;xr s:j׮5?^;ҡC[| _dgMpv'NQEd7VX!!.\UWZZ.]{Z548{oacǺ{]texxLή>5`ƌ̶ի1c"5xZ]f̘2umG(S +FzuR^^S݉cGpU:ujGҥϢEs%?0C0vgڴY|iwٲeSJՑYkE-̝9sf]rN+xz!22d~io8}fK6k֔gfܸiL>e48Sgѣ.s͜89}BNt;haOJoy ϵ0v4kք%,ؿ:ҥ+h4?  ~T# ujԨd;ht5x>⚐GٺG*T$8x^c6ٳg}Y>,ר I=ALJJtyU_33SlmY;?u*7XZCTrd^z8v,ZرdPgw)ť0Weiػ`mlm2??olEm.+h,Ðcyйsoc~;(t.^ԩ^tz;q%&O$!RRR{VNTR͛}E5kV#(h#$$cԙzm711HII%:ӧ{}!:Y}QOHnÇոʰ_v")!cN?JJ|ŠB[Qwtt6 0i7kk]g,Y蓨T*6ms2L׹3nT]cV"baHü΃'N,>}z$Dhc8t`/ K`P~eH0^֮b9K8mp{XzUV6Oo٦(LMܹv,_@!"jP|jJ̛E% &C&   PhJG|ADMADAAo4ADAX5Aġ{%"jT튊PME^YB`ǎ`}gڵEy?~2oknT*yTX[l DѰti^ҥs}BsaQ(=KW>ȑ#믗+«Ց89ij%,(-'6 [[k݇ЪUsz,^:C>܅]?Yz-3gETR\ڷoĉ(U~+W݌o]K/{(W,n6(+\~UYHx}(SM7o}mپ}iXXXЩ{t^rאcm`,VDDDᅩXRRR[6C;ʷR2e$(h.SHH+^2҄{o055e$aaGuNpD,eB~-TÇعs'N2fp֯߂wmgX/4m}CG/s2'NAoߚy}LJJ*9 ٷ ϒ!zlC̬Yӈ>InszP^]FȖ-!EM+l>O@epy.@zz:&BK,-1~HYhw-ѣdf̘HvTfԩSsճ7l`ԩ9={vs 'O(_6ml޼g`e3OL7QTT`I׮Y6 6{ff"eʼ3 ,[_޾~f-~;ڵkKIMMcڴT"Jd,YR <d6gެY @lAJW}T,*n.;.\ĬY󉌌{k_{'_YXX0tfΜˠA$''掅E^w8y4}R5jT1XBm C:wZɖ-!:tî]y U hSVSNХK,.]"JAe6''63f 'Ofڴݻ'Cv1k~&oU>}z6---K7-57n".,qqg9~<͛zLT*3ZjNVIOOgl?VxO䒩?~ҥKɷPs Є'^ZOk9s&6l_&7jfff̚5xRSSzo6oA>.!(Mb|,60z?͸\<3-^ݕ֭[dXxjqܹC=ĉ38s& 6ӽ3sEf̘MT RSӰbgr^H~q}K2oҢ=IŊo^_|1/rMbbbBjUٓM̝XwcWN<͒%+޽+W& ^{֮}|iԴ%wCm+%<\v^QAQQ{^EA5AAQA5AAQADAADMADAADMADA5AAQA5AA(VG- P1}89Pq611BK:wW_ D mdSS,--i֑ѣҲ E%SpwPh[BB f$$wlT$ɓSSSF/g BQ5B6mVn̙]/]6l#..#u^VdeT~^*֭?n]l3}ҳglmi۶ ?sVn>RZU&LElf);Ʀ9wgӦYܷ ݺ9acG'555Oۂ IQsph\ @ѣ9zt75kVk^F13́o1q܉:5Kr܏7T.___63nv||'ѡ̝;E{BCpa 姟V?eyA(J''7N3XNqEөS[]Νt-,`^X0o۷YQ^]Tzǘ1 NH֬YOP VLLL(_ޒoر#t/]""A\vԬY-mqqgi°i1cLKKej-an6m޾1g>:GϞh4!AVG>kQƘ1ShƑYQlөWyv™oZLLLQرQv v8uu׷fރmADP^ԨQk7LB9N[4Jؾb ӧȑc<~ŋi?)/3u:-]bbNJt)<<|pq>r>> MRCr!CF7Db ~,^4&Mdl?*T(K<=趏7qq 4A1k߾ ))̚5?xᒯ#BRI|A{ ҏ1cp_TTӹsvGGgpa'{]}\\7Db$p^U!FM kWԾY4jڒ;w NPvr_AQA5AAQA5AADMADAADMADAADMAQA5AAQAL ycZ8[XS\YիGGB(V/?VVMqC ,)ܺuS\;PTAM?ՑXY5VGʌJ*  ==+bժ Zuu[7'llZ_t714l[[G\\Frm=kn}شK>DE`:uꅍM zr…Kҽ4jwܾ^6kxL S|A^9QsphBPRʔy$$D^NijʨQnرK<,,͛?@h. s11jLm =55O] \LT:uj(n aʅDEmۖxxx- dڴ:Ⱦ}[)UṢ@>] IDATm/h3ČPW5>AՑOߧMu].^W6yʗ}^d%fMή>ffTR /)l޼]Wg haKbճoW~ܽ{OOc OyѤICT*3ʖ-äIBߟb7 L5ܛ5k?AӒyH͚>:GϞh4Wv.]sܿ [o]ETٖ=|Sv o:II }2c+JZFasrr+)ŝF AVOF57^Θ1ShƑYQlөWK9@yCf_A pds4ӥ֫_ߚ{Z'667XZCTrT\=? Fc]AXXXT:' 76#G3$%=$)!2dNYv#$$cT"{ czzf]AFvٹ9ʕ^89}F.y,\ɞcgW:Ә4ɓٳP<..S$cQ3nƍ7h4$$DdW4:CGAo֮}|iԴ%wCm+%N][+<*  & "j  & "j       & "j  & Ց/n˫~WHԜ E:tAB9_݇US~u^yby:vY$3A^W ˎ<8zZok_&D)8A(>֦#+;v8+Wb5mڴ(ABB[ \H?~\N͛C1c"7 Xڴq$44E׷{hmڴ}޾Www֑F>۷koAusƦOjj؆ ʌJ*  ==+ZDQ~]t714l[[G\\Frm=kn}شK>DE`:uꅍM zr…KYJ,w>}6KbH|6mԗtؓMy0X;wV>"$ѬY'N2[e}zADФּySNGܽ{'t￯ssf͚.[ȴi_u}RT)Lz DLL(?s-!/;bjjʨQnرK<,,͛?f_nnc8/GԬY/yzvwO`bЩS;\]Guk+W.$*m۶',m)~-l-d޼DG ku>dÜbQv llz6~u/:7(myش 1asvND }V'Q4nl)MS%JXΛE& Q([ &uۗ,YɬYӰ)UTk 7o!/;`m]/M<-k haKbճoW~ܽ{OOcr5%%#G|A{uݻjT|0cDRѰa<<&bڏ+~лys.]O^uLju$k֬'(h;yڶmɱcQ4oD'ju$;wȑcm׮vzh8CD,DcBQ@) (Ė5v b5j,kBTRAŊFC$R?VeA4}]\g̙=Ü=O*IIIU>?:::jߠA]ڌ+1󉎎ɷݏ>R4qD..N+_BZ hFMfŊ)܎=#FL6?fL@DYLRc+++TRPAe\rUX2e =qptt`lV},7n^_`>9T?yD%sX\xxgpqqb`勇m=1y'ěT а!iii\~;wѨѳMMMx ߸! ծy#9ӧXNڿ.] U{2eXǚbcO{og T={氠ryãhYm …/lp {eޏ"O j/8՚K~uSFWW‚okkB9z's.!88TRRR9s&CdddA_ayqկ_[wFBMۻέ000Pn``s+=u[ddd_ *Âlٲ ԛӪ=e˪1hP:GZZiiiDE<5k 22F%OҠT\~ܲb h9AmĈ |8vv .]âE+|:M'++ s<<xsnߣqccNxJq͙ԩ̛516߁<9n:1wRjV.ߌ;]Cgv̡6sѳ+K~M^?g2kBn޼ <{lqsX0a$&+$$DODȾqNac䃞BhpX(f2o cv;nƶYڱiǏȔ .Eu&DI,\ud!AMȆ+x,j@&D jB^rY^O !&BHPB!$ !ԄBHPB!$ !ԄB jB!5!^ye9[d|B j/_?b loߦM[17oM[_K..$$TvQl8x7nѦBA `ԨɲbB``0~~S ZsttԩpmgϞv^xãpt'I!AmŊ،lغu[wԞNz{`ڶ톩=ݺ D>w#ffxxߓUݾ=g.6M7mѣ'ҥ88gdffj '88D\|J*н{g@˗pk~9`eĨQHN~R<72|`"#Uh[(o..6ŕx7nBV16z|E;!NJۡCؼy'h֙!C̆ ˉ=S |}*{zݽ!DDРA=+˃CX;, .. Y;>CCY|S9>;7qM-[ke:'w ?)8pU~ @Ϟ]]]ƞ , 9ΪUXxqq,X0uUg6\p'_ܿ=A4k ((k7pի7oA" g_QN!A_ l_?O˚9+>xx?_u۹s؁-˗w ?~$aa; sʕ?)*}^ٳ}0GO,u" }:wܧm[g X1OqdddESBBRo Kʕӣj:u,OG*׭?㷴ldVPM͔hDGbmm^Y +Wchؐ yv|}'ciلrj6mڦi^ZWعB9JUШ{lZ>wJn@?8tttWBRq|N߾quO0>8NʼnrR2 %'NѶ'z\_e*U*kױQ9y_ɩgҼBGHTT :~''> ?)Wm95S0j m Uy ;wBY+mԨɬX1;;ſ6qhČÇv-+W".TYYDFH]$$D+/Pf~X'Oӹs_z6zl?RY ^ZT9ejL|_-",Z9-SSs'kWKWزkpJyFĜEfm11Uꘛ7ȑCzff03k/ܥc^xzP/91ƞ@ѱɏZ=Q#chٲrٳ4chؐ4_;hSSFF :.&&2>mN!+EIhc]po;/ŋRghO]Bpp))rLCQMXX$))O gDu޽pvn pvn޽>>x222WQFj́KںruBa7|%Az;ݽK0s'ke%"̙ԩ̛51IJڵkGI;V6͟,,,3`@/V@\Eʕ֊+!0p?'ɷ[N̝wZ_.ߌ;]CgvAmĈ |8vv .]âETv$5 {q}j׮;;wxfo gN8Ɛ-3S.]^62fe r^{+ _h Lۉdffr5fѽ{!x?; ݻY=ztãLBHP+}uDnd"5ˏB!$ !ԄB jB!f(r?"x{ז9B!AM!&BHPB!AM!6sR&A!$ZvmvطkB!At;vp/}ű{,B jV|\4XWn\|E8oIpRi߳o>;̚6ޟ:г3&GjvmQO^hknmn2>͔S!ޔfni%ywٲk?[|ͻ%1)*ShMeVSJPSG[7]*QzMfMMtMGS>W-ȷƠ̇̄>q^|YQg~w7ao m\-gB)A-'M]ȑyaL]PH?:Jff=c"(b"Op.4Vʺ7}T2xCFw6~=[7b4Unqcsʖգ5q\B"(_oZC\t8sVlBJ*e7_fggm!xZ5vH/98vp/aoT=Q5s K#wn\O1P([Ty*+PИŴwOMضq5&f藯|u 3\9}]ws3kX>9V;(>6il57!(RuK4SG`cJ%Td}+N9ficϑX7k u ޭ~@rpNHu g۷3a%ڻKٸza$5'(9;Mj/jWD;tQ9֞,P,,mTgpSFѶ?16nph.ܻf3;[ǧ]{)d߸~J>6q23BFujBIq-D - Dm\χ&DIr3L/A_!5!BB!AM Cc"q5!D v&<Cc3ΔTRBݏfu$%MP^ؽg/-[:UǞYZ!d& 5 Gg;vTe?ӱM,_He?MeyW7f{42{>ܹsG,ܸ}g(Cc3Zjͱc'RW٧,}@]e?MeDGsw1g~ttLu?IhlfIܽ{Grfæo_Oc٣f~uٳf "E(~H0zg)CRR5j(0usfϤe ӱΖ߯!P chƶ6_8v˖$00E ɉ"d&Diw~uU^Vq={tc` k6mt6lܤ*T(򾙍M6ck>1omlIOϠRŊxr1_d媯Y~#G /p>}e@L4cO=!AMQU5ek=K4+:֞ zr4?v쪼o7'O†gvߴ4>|L4# +fyrTXSG&7Ss+&O~jC}M=-3?z~0$Q~]Fcv;x(K!1u~ȸq#hιuěȆRƆf/}SFff&S0d;&r2"ɉ_Z!1`piJ>& 7YzƠ{,^< K&]/FXZk]G7̚!M jaj֬,ffXB՛6m/ag=;;_|1͛biu!J]ɭ{jBX慕ZV*Zlιs UG!bs/]:t艩isZȂ+HOиoNUլY_PuB' )+)ǎfB>6wc֬̚?)zr(UIBVjO՘3LJRlYׯ˜9ٷU{_U=|DB jڂ-7+l ںi!Vl,~>}ۉLGNUQdР,_sgu2hPB U*R?,{ +t߯sJ1cXKP{4mjg1j$4iA߾Ciذ>^^ \y{O{ gϴ#^'ORz-ZJ zGiieblđJF"pvnsKuQC:tpѸ6ui]4n܈w:_tA{볞2o;vҶM|@jj*⛵k8x0)))ʲ?DKԩ|fnV۴ij֮K91Q~S!-[s4VYS+ ![$ MKOšnR mԨֶ|-j#hk5y;Ƽl``bڔ}dނE44jq#s~uZ8:qZLLUW^>GDPX|ȭևʕ+pN1;ӧTC5j}ISmԩ0?Ce.S <>(0z8/['NNQ6Z8SZ5O 02_l# Gn]t&<7M,ō*#pڥHyW߽z QZI=,medd0_L7~eccp6~VN8 { uk(Sk}οr.缧&+5!ĿkԀ-[Ҁ3V߬-R@SY-k+6QDQd/J+UZJM!+ l{&AM!%HdQj ^9"o&\B7c5Y޼mBD9"HKKcؿ?;+uV%EjSG6meL0wwM]\\Yf!FF+>Uwƍ[+G͘1c*U6EfmS˗QRw۹|&j+2|`*u#"Uѓ,]7~w+ӭ[gƎ5E۶7{59rݻw.'m^BJ-禐&7`bР>{""BAz,.T_!_K…_ ֮݌DbcOrhxyR ` mhjS*m?}>>=_mmpϾ?ѕHNxFӬٳ/X guOPv7YL"֯ eѢY\r Vha _02jX`v`ooKyƏIXXDڸq S0{1Y(+Gժ1uXN|,lGѾ}ktcddd[B4mjFTԳ ѱX[[WBʕ6B^ٳ}0GO,u" }*=7KKs|}'nݷr LrVk~ˏHb|R XlS(,_\\_q*III}lĉ0\\ TBaɉamI伯ԂgcijN|_-<,NN}6@aO޹Q'[[k^.'o8 jTGܸq 3F煣gP{deeѸqEQ`* Ǒ#'Yz'Ohj1sOY3Sq)S&20UTQRzymJ۱i]tOAT>eʔ!>Jy yO'-Ǎs^e[ȖNr#"#c=]l "#cHN~~ IKKܹsFe<655$~6Pcnވ#GN88gϞS/xu&A>n%2m?7nDFF&NaȐѹVtغuiii$$;@-3g ##s3nJ;/ŋ[1׬YȘW=s+ T܊{сKں2݅. |֪_Gd%JJJ*gD1tzs9>LrجHeo7B[CZ55jptĆ [3e9s|عs/ 2Ftiߴn VcЁ/ ?_|1 |W ==By„L+t)߲n:i сʻs)غu*Xb۷boߎfڰj7ʻ.sxxg8/6mq_1b*}+΄G`hlFX(t*{q.7HNkMh&MF4n܈h\.L۶Ryx/Yp&pv"\| /YtE&-ǎt;Aj;Qohb`E*i*"bifߊϿ_}PYҶ]GbpL8}  99& eu{nݾo?7~KKkl{MU.&&BidjA}s>QIP+2d M`Ĉ 85 BAam!6 k:,Em:Cٲ5啙cx0O}?]t|l^^S:MzYYYٳ OJJ ?~zsm"Z|ƚ 1*++lقQ87_cQG!J.?>zt?@ع3MBT6͕@SYԥӧ42P&6*+Ce٧bbFO.طo?f1gBmٜo?RbE6M7Up: 0oLسzOZ::s|>Qz/%\үIXFK2$%%QFbG__xvꝲٜ ;o_l۾YOA bn#r/G0_C-%޽֕/)z}(l-lظIe_MerlՒ ܿ&+ˬ,'۷̬Xڷe dddcc6ck!AMQ zsk`WI)$ /@\9=V}Srtdl޼_XZ6\9=;M)^?)hьrQG̟?C|l,,+K:"0p_R\䷪pm)_*U*Z: ?ѬBNf F||5mՎ#> nnVIHUXԽxDGuull,U.i4\~Ott K/D__YjMڟ2yJаӄ>¤^x^"βh<˖,B__!i謱ԊY u𳤧gϿ0q|hO]Bpp))rLC)X^W?9ׯ֭HKK#!&*wJmƤM;%ԴM:h`>U뤗SF$ЫVAցg_ݧvZ 6^T9t+W~Í?QfuFG*q%0c- 5s;>Su65jTcUܹU$j׮G||ffLڴoW$Tˉ_Ԅ(!,IP僚\~BƐ&BB!AM!&BHPB!AM!,m jBblhlIJ!5!J/!~}{3mLԄ(J/ϿXS2OCc3VZMs;8r(WFak]V9rLY7<~֞GgG6ƾ4% &PA gpД3gӡqy4ГG̀__wT]l~޶;h׮-VR`߹IR:w? QݏW+&| >S&6>O|Q746sSL7UyBY׼3a'\?\<Õ2:ql5421w_;OMӾM=B M߱iw _e$BZ y!W#AB6h`IymۺDRRm۴Vn$$!ym^I>5!NЪUGm۷mWLM~aO~9lݺ֭bjjON@PP0mvԞnrvr;xz33<zv7 sBXcOM}'t&2vbh@Y?qtjǫ=Qy%(:%h4ghLY3F(/ ^ݖD81󉎎yNse*U*8iO!^5&LɞqhČÇv-+W"^Ra6 !7QCΩlP% W.]sժO2eRB j%ؠAK\\<7w>:5k 22F%i_Qԯ_[wFBMJT{BQZV],6W׎>ax/ݻOڵts:&d~%;;h+9s|:՟yQFu<<?Ĵ';uLoo(!(ԉ# :Z&I(D)I_-{jB!$ !ԄB jB!5!ԄQ){S4Ρ5!g#046#,쌼pƾ ߛ$ !]P^ؽgLF EBB'=vp RS}g:vr 짩, c5X)̾!5ׯ46mĜp@rr2M,$'?vIܺ};U7~KK546E;vB{M]%''ӽGo ._ޣ7L-޳wQʽvr#muĤqS۲c.sw͹9t6 ]yۏY~\xm[%6ڹ;\t>v$w%}s]eYdY ދ/}89Ҫsx|>C<synr٣f~uٳfh=\tW羚6_8v˖$00E i5漨 _$+5Bgts몼v%z|HfoIOOgM*j*Ӗc_Ǐ0YYfeٔ^g=پ}fXB|߻-==J+%UlmY~/׺'L0<#o66f36Es~}e@L4cO˜m8 jk"- mL(vAA{qsz.vLPг |CQڿBL[3}hʙ>|fa.nn]p]]]_ ؟O;vxI> Z:Pre2??o""0kbo~ڞGwr]̯oޜ<J Nowǜ&Mo VL3éǣ͹X z\H>Bضϲlٜƌ-{wEZ˧&(XNZ!t܁$'ѣ?Rf޶\\\15m+܎=prΝ{^(ҥ88gdff*oܸŐ!rW&xHP+Jkךݻl߳GڷwRvf.'.. fz;oǏ; F{o]MTT<44?Cٹsׯdٲ:FMɩŝo ] IDAT'L!AMhֻwVR;wW/76oގd,-PVVM¦Mmo MEf+Wz>b*g`aa^YԩE@os>m:c``@rzXXb11q(S\9͚)TiLQ7mʕk۪/>lOWo sld !$ƎA(\ YYDFJjL6]Ù3Qz's.!88TRRR9s&C(xx&,,T'3g:D !:rz'lwuHjƏ޽Ԯ] OOw\n[;Kq'j֬ȑr;V6͟,,,xAzz.RV\)779k{}146{#SɼǕC>|-D ͇ fܾ3j}UBϾAzׇ>?Sy!Ӧlٲ~ܐSYd֖bſ475/Y Q  9¢˘?/Kܿ(<6Q$:ss.LaTedds.o?Sr'O]jGkJ.Y!556iJ|1_d媯Y~#G j (37I*AMtЎG1+̛*1 ;; 546ʎg0x@;-ϩg>̟X4%6efҙeuU4%̏-TRŊ6j (37IZZ|NM]iN>i> ⎉$B#I*(сҬ5͛I@"7!^ʫXɇEQJM!5!BB!A02)}B(RU~"==+aCܿ+bkkŀpp{msP1`iل;7[޳`.GGMy_y/N_}5lذa9~XǏ$""+Q(/bSo9^7=)9:rٷ ]++'FDr#:GK~О V̓2cT]]]V}-[|jl4;m##:#Ge/l_v3F QٖxOqXZ:bf怇h~=Yq ntF`h},1׋\~PT{iǮ46un:uvc/ML-ٍ'Nc[v3>>=ѣAʔaԨ!|\iF LR|yyǀGJUZݻ]:SjUʕ+-׭Vx,ܸ}gz+Wڦ99r+VǮy+9BjWRa7vMaUwfh՚cNh|[yi?MIS5J?*+%%U8> nnhԨ&&vboߞ4~q.ZhFb/̞gDG8m+h܅myr_~͛6/KLСcrȆM[l\FйK7y`친:V:C6W}!tq|}rD>$Qfz33`[ބdEI,4%jqׯ^d¹̘9[_]muiJZP 7":$C&20UT.TUG]<ʔ)~9X)j'5sdgg3bG煣gP{deeѸqW6hPws\l,7oDy>WS'k$-Z}Rקm[U1f\;e^a 9|I|FFey&\d2fKGg}DGǰtBq\FϿqɓ'l= -a63fzI̙ω<}T;o4헓4¢)m۴VI}ʝ;󛋳sW_~j֬Add'vmf׮j*_["--x{ a#:KZZdK֔PIicx6fIJwSZgPbEYdcTWyi?MIS (VZ)`NJؾ={v4kֆUoߞj5j!tsswalW_~&LɄ >7̙Ν{tdȐ1*'H}bX)ұ5'Nb7hJ ֞G)lB;kOiI:yx.T?;ڎ>=ۋ+۲e[bL1&H$$$$GhP`0 #? "wK꽺2}suM6&YKkN3gΙ^#ntޑwjX7 y xnX o G.rrrrrr \B-'''''j999999/ڏ99q򇐓.~9s8ysrrrM-'qӞqA^i$'Qrrrrrr \=~IdEyOXH4wٜ~)|}/zر㎼uPNNN<2wtIo~nn39msş㠔կ}/oկ}n !|_ 't.gt^7h4w7q5{Kضɜ{Ї$I8\~?ǫ^,;l>O}.[_g=l$o/_~9y\\;pc~2[\ wMz|_T*wk.ym]?vc>r"޻{}=baa<#{7p啟c׮_ _9>c5|C哟 _Wq_U|㽗wl|o̟σq9m}?眳WLPJBG?:tlbxxu\w ?N;2ٰa|\y嗏Iɫ^r>+~@^^r<#n-~)ضg{s W\/8VOq}s> ˲ğ]Z$go~!9thpo5VubNwwo};߉j.{E]HZuF;)?}~W_} 7kε?~ IKO =:xuOߺ. ?@{_ślǾw_/߼?Dk?w7t-|/?8_yO;GGq.YDQt0q[HPxTc:?N ?q>ϓ;n oa8jy&'n;!mr.QqOxnB)aѼhsXo1>>Gxlff6q[gH8a |C<߇fc]8_\sZϕ-mcq\?ヤo$I8xpKQS,v's&*|Oa?u<ϽiO=_nwXXX o|C{>{?p{o?3sOE|泟{G{ģ3N?={ca`;%o~?==ٻ3N?1< ǿÚs`$ym{Kt{ͫxɧ< Ox˛՜gQTvK/}'߻FN:}]f}91Ma?u~勵/?}󔧞o8?^,Y^^5~'W_} v6^w=yG/پy;8)ol; r/qxsz~~죸{d?ngNΏ?m?gRO#կ}==bDc|*ͅZNcEB-'j7<^yPHSjpBw6/;XAXDHMPIJL%Ӕx4G50J)Z.츛cY&a X۸85MVX,2;;r8 9ph`@&RJ&NQ^Gc1::Lj5h44-k7wq7r '|20pywn{we6ã#s` :- &MSce#$b`bbݗr%>wf,-/vv~( B?0 EZCC5Jrƍ3J% h5t;-$!SzA*+u&&@XLY]_WfV-{JI?\W_lI=xʙ4-V1BhQB` I$0 *õCqJ(TT+ 3Ŷa|崓az@)GM,64$.~+븥Q:cg>Wu"4,-b{%ofkw#0 72T 2i `Qhl&Up!:b˲h62?yP{ b8Qr&]tLT ]OѠ0?R Y7{ Ð>i $I71>>N:0m6mcJ~*!h U& CUp1iw4M###޽ݻwr1[x ^@o0{P,F&дd$@yq"zNC^guuu=1\.#M0: Me!IJ t:A+022e4-*^rɥ,@Lexx-@$N,I\+mH,v6D&K+x@lqJ'>XZ r-F֠BLFiI}TD-H@jA ]_J-<36 Z8Tt*V8XV$՘ıMz={wŴlL&vefi115[hq'g]yAHVpNߦ~RĊ^w֚vCG쑓xjZ%h ː)DZ4[T%JRJZ.J)lDJIӡl$ 7ofKӡ?EqH҈C8p}h:t0-MIqqDR\YY^ĶMFFג+Pըj=_8x3jtz=6mwk FFGiwZ$A,"˞4$m! vF"V ˲(qeۘ2L0IF1A8,0b3=58aQPJF!RdmT*L#֒ZF%EPtL=CK4; O7LIR\BA`]pPdz֨8\yFB L! Dd#tBK*$VX&;1KQ]]&1 2Zgh[(JAvA}׿V :)!f)0>> AƠ`pAW贺4M|4}4gǫP4Œ-e80$J'LLelۤiwNGl0UjqSX]]h4ØYoΦ6̠tBFaHgfS)EDaBP0LzJ-[0::J\7swȶmHӔFAJ)(b00 j >IeZ 0AulJF81MRߏ0|Dz ($ T.PH =.~R* ;i,[DI2ED.'t";v|y᯿)zE"?BISi}@(@c*9 j,Fa4@E0@Hldf:6[D$MHQZaX`heXh%uaWtRv q(QJa&%Ǡd($)*IسgAQ*~{t{qHTo4%R @{4M˲|y| ReI\axih4-؞MPT`:6QQ(XZLreZ6:|J#eJUJaLb~vb̦MhV}RPUX333A2Bёq}yx^0XcC  1>9IP`ddvڅazlZ°2 9 IDATDOad|}Y$Iq]q-TMmckez$A+GA@beq0IMuOT`|r AW,P&I",Z.gvrne7r Ws9OP, X[&6 " h@Fc:zZfCkTBk(V 2Fmh40MkHı Õ"aR,Bff%J%tC"$IL&N;m9~Ҍ43ͬv*J&Aq0MӔ,X86?Fl[R,:k I^`0 IofqqqW$:XAu`~*ejh7ڄaHT! ,բlh6v }l^7eܹ GRRPh[&K(,,,9c"$Ih5FGGZj"󋅦eLNNRVvT* J)2 v @JA$i!abb 2X^^fiitH^K 2\('`4Mq,c*bnv?H9fkqL a94W鴛XӥXGUWIiBaj Zb -33T@H,4)ZJ#KjRZht R@`251D8V&UH AD%Hi$ @&'4tP( D`Bk6VD(P,3<RJlf0H\^7;_$*Ų,l<)#P(`YA?3qW+HlӢZ266FjPI޽ Ð(1 @Jӱ) m(D+E%J6B\{7X:;lYc~v!3!QZJj1I sC""Mh)Z&(BheC$0ц@IF &M33aRs\ bhL)a )1,^% clۥQj3O}Sx[H .@'2Ib\}5| ǧP ÐB@'OǴlVZtgvv˲C o^:NfAVcyy˲0 +++fcیs}`l94]RR277*͊J 233Ν;[9Sh6,,.rG395O<cldʖ5'8F&iNSشizr2 W)fBpmWRM"0 Gϭ!ã q'XDxخ(SS,\ {ݔ] [  M A鳼:d)Kz=,z aL HQQ HQ*{K& MBLC-%R$Ja*4nbCvcZӄ,2XR <|H&AҨ8B' 2Mq2F}{$ILX""8fd|%L(h@$0mgM)JֵO!-ʞ={e5]ߚ 9RGjGjbyE]k^|y| C/.a9.>΢KKKܼ&utx0%*MY^\,dy^aLk:;ͶmۘޘI1<\öm8Xa{i4 Oաjq&vNpR*W)Wj++4bzop}qbN[HӔ( q=/!h0`naӵbtx~؆IPIKq,a蹌}?D)~gySZ3CI&(!SFPP0Ǿ;S0FK%&m"b (ĭGc03s۷s0cO:d8M}?O LP_c~E4;F5A$0o#0A,p >i25!$Jb0L%@ H#uc,eF4V^% N@E!ѠOB6~WXfddqV]$BfN?L0-0NPIR)&YzqFijj]M\qiW;o`>Q>?}nbCjk99{v!O'Zc6*I5*!e!HB% As 1+T); ag {A,WM)En㤓Nʒ!{a dzǟ8ڵJFzjF <ҴXYYA6f355M_˅`Dh)r\eXxa0L4HiG#z! K8K oͬ? !U`H40-RD x^6yfܣݨ#2&q]IH /L~#^KM\~ߡzTia{sr~BM&#[+@KH)׋5a\-x|ki`-T?K aa)beekG,y !".^zzC8 'C9<|hhz}/~߯y+Pf |Ax}}wPSB ܂GAiDY&dTA YC H "MS$0òHL%0 $oærw)(V}vF'Β;n+("266m@vo` h`jj͛7sw·\N@wNk^ :єEE׵)<$!?+ϥrLP"Crﮝ,-,F1qR,W9ёq&PqHłA݋.Q1cQxMRI? ?.FlلN("\K@ř@*H%%0&t@@,HD?PAc؆ĵ+m3*EJăRY؎hu8l#Va!p\Ȳg;2J>)#tXr qiwfYHlk .@~<ΒOsrr@MviVE#kLs)F' Z)LD ҂X)aւF+RJ0,(H´,LX/>U$k3LJĉB&ضǣhqfbwޅ혜t6')V ܹn֭[i4Z,..brˆZ]8`dd,//dblzVhNN8[?4Mٿz)336`hhT+&}\K*4ԗ)Zoaeij;s[Bjѭ/i9zxV>`fL6o$EBBښ4B( tX#BfkLkPBtWQ[R)m*Ed E<+4 * :1' ґ2x-KKC4=•: KiLC MiBЬR(i1Xbbr8:6wzaiЇ<"srr~ҚZ H#B@by^fF3m8i`^6!igя^ V謘O `flzDZ֫jml àX(,pXZeMEG(xT|E/ua4Jz0 sl۶'$=XJ>2mq[۲bĦC*ѱN9/v `ZŴ]J^-07}{Q,fօbCr EYw% Z"*5PQ3)A@쁽z=$c) =;>R%xrϪPuݮ[Qv"K*|JTA 1-&ФZ*3[ afBaPp$A)(IajlabDR(65׿[Y]irg2==ũGzR,X\mBv/-㚂GM} ւDX(%PJGa~qǟ@Ǭ RWp=J"n73m̢r-03ArrBZIrV QLBPchhq*i^^GE UT*YqpCe9cn,˦fN9y{?<7ؼywi>Epݻe`ƍTUZ~:122“d%FFF8sY^͢#4 hDh[a *LNoX+T0 (+8Yg-),//sucnn0,v!IC}M!&R ? RU]RGMaS_e*E~"G1LzLc )0M(M6`H p0DqN#G RgU[0ơh=@Q/뾝YOx~g;7t;cuNvS8̴<2@'1c362(E462L uV7R!ZT %6Ms) #<*4dz!4E|SjUCi \\XBkBՏ uJy8(40CjXqJ'I" deNJʓD۲ri4;4}0O|9\xSضu * w|$A0-I5n(՛Ľa vI{$Y!Ξg3>1EoՆ1,ijN1<4D-m<)mDj84f6nTj12<[Oɵkh@PR.2<\E anCD+la(Y^)~q̖a0/ꖖ븮?3RNB!Z!p1}vޙE\0$'p<@fVVJhv K)Vr~nv2!4YRױ8z4o3Z{  ))|i%1{Ew,޻q8*:q:@ ԙ1CB1T0Y߾%Е+Of!k} 8V(3ӲVUlٌ9:LRSL1ͬwY 1v( iJ&Oeי7>ǔCT AbDI)k%-VVB2b E (檜32FᆱpZh-Y,-,Ïs y:DZQUU/+[ZY.Td%M6tS_ST t,PsjVƺK ׬ߑs4?Vߨ `rpM=zD$1|9ji4 ޚ٨@1,ĺUMQY3Si$ $Q۬CVݏ(o˭[ƌǗܽ{.q]ѐ,_G /WﳵOSK0ܬ",K3I >5]6Aݎ ͘縮ˍ76lZk|ߧ뭧3oc6?ɓ'u]q兌.' 1gd!E$onc ꂝ-voQ rdzNtJ&9^F԰ DQ+e^Z%UhW.*pd%T%D` fM/8GSkytOq\ΰ=nʘ؅0~VD$L'#yM8!֨UiFieoB l4U^` j.Ķ^~mH"k)OG%tۿS<|O6 /ZǶ퍬 Ue6mϮ"\sppIӔ7߰/'$믾41M,)\74HR9IVR7fEYr0/M3<(rZ6p`qz%IpMvww<{ UU!q9||=秧qDYt],32o6'8fgYx^@n|joߦ6MJyktxwY%)U Ϗ_3>yoxݷik  R N$͖"at(3u]l]#.UEdž-1I48~-b5PlJ!( PT%ZIlò s_̬uSTJm&E$iIj,ln vwLS('t]f)ir}n ɝNkC`ݦՊ+~pqq6󥙠2߿mmnaqoV/Am`Jx)%En뻻19|~w Dz938@s#Zqg vvvE 'D 7wwq낳')Y YSӷ<&iNs#HzmhCnu[sy[ZcY'''<ω␺6|Nn6?쌸E m,}{|eX0N6r$ɸs~~"QuNCxrI\!M}21[fQD?]_萶Uwy$X8nSu(IȪ$+qo)-{EQ-K7pfl6-Ob IU7aD M1j ꪦIVc}thB"O"44>y/ v ?KVld8K~}>)st1LW(Y94A**we9hUpYg6QdE@뺮7o֏ySM `m՚i(b0O'SRP%(D -\;FeeSBY%)~ﻌyjD~v'dwwm~񋏌q-.؋ݵu]l!LhNپRfn=u|&Nڦaeɓ'OFبͭ,M[ԥb1[=yRڛi"MqD4 hQ0D`lrd/cdʫғ9 ŽF+ڍr:'"RS[VS96]7oؑ8Ҁؚgg\TJJ)i|RYiIfh[[jB%=ñU)j2orG?c>["v{<~uDjYY`{1ۃmhE1i])ʚ-1MaF {xxbno@eY[Fl^u]6tcRb_]kC3wZiprl\cwn[Wϩ,(M)%eB#plE:ENUUؖ;z<'8`ooh/x9场6orqo&86jUUQKEIc˂jů~+f{.2Պc!^2arlX]Pun@~aUVU*p}L EUUe. P"3lBEQk"NdJa7R%xCȆ+-p9Lk湢6cK׶R!m-mD#v,-݈e\?q~w~O~KK-c`OdAY+*%}`="[YLFxm,g Y$ uzƋWVhy*)Ul&T ;u]כZKWGF[[[ܽ&I...YeUYQkUC1= 󔲬Ç_g9B~7g?|xf2pOqm8]FjX-Y,WAs,:wLj2ZX.m(BBC*cYaaY6)&//@4vRG)-G]d(s,E]44aIT-,3Y(UR3IRN d 1/!ulj,eUjh^a p-)mh4VրAvlBXԍA55?Kl! [&YKPW~Ր6)^bxNRHo9R5ʻAs}<7j1Պr'?~zڣGx뭷6$I6oL؛ɫ/iV)ۄ|bRR[!rRc\WI~Dضd0kwNl!~ۿ/mq X.gG\ /N->C>9of`eY EN]=ݻۿM y4mPYAo駟r||LSU&-h;~p8ӧz=:nwkqMY(&X\<ʩ˜rnntZ ]p]P)cN^/m,[X(c.FG4 -4Z]@Ren]kX6EiƑ  Gb q, ױp,ckQEoC)˚/ӂgIsΏ;#~fZ(t@uR6-5嘻oqwxo!VG^V4ء,8::իWLcvx(2"u]olSKӔǏsxxH¶M#&Bf(,<+[ܹw[ ycaMۥjE,g_UCӡ)$>#;ܹs]NNܽw︨FJA+Ѫ*s%G_0 "|'Ksz>ޚAHmV 1<Ν;oևWpuq])@5锼TH0 p fy4 qZ^ؠEE“FHx|~uzaLGxl*!1_sryiqq1A[CQEsX5PjIUg ZdYNQTHRQ5e u!@۶+`@FDQDyضĒJX[EmƱ=эD ˿|\'dKWAj•nf萑 %n?v#ܐZ#U v 2/(?ISw]u]ohSRnᐺ}'ZȳfMYh~yYn۷}I.KF<f3+~ӟpvzeDQdIb6“;Y.7nܠ2()ǥL2"Ͱ-A]& .裟svvn4x<3fŦAmmPF^˗F#0-ˢle<Ë"4?a:{qƇ3LF$1u IHw]vEaOf%t4fUHBϦJLN(V :{ s^pp84‘5ʐ\?(vO~CʲG?ЪҕI7(ܞIJR ꩬ6rNZ='TNᓏ?#Hq<.9JTĤ5P5\vE( {Z-.kjJG%锪ˊVc MЎw~`.`5ŘV?%`oɼ" \YxD^؎v;[7o$"3y9GG؎cC4%Xh4y!$ٜ$I8~}Dct>DtNS.<Ǘ1"p]MI/.H)GB %8.tUZRU%ư3cN.+s䵦9ܾuE\,V4gxvx<-T]a ݴ$io)]@뺮x,o[-s3SUEyW|W|È;w1kb en4D:f/?ܻ1cxb}|+d2fT%5*3js34u7~͛gYF %JCY7ܿ^t>S_2??IJ*еm lj܇F)m/--.sl6<ِyFBeQ DM#Hċ<,!uQq1IS&KTQ3l*V"+±!Br%*Y5v#laۤysqqAGfC,~;;;Z-PJ14lů#]є%6n pY v8}4.9?VZm=X7 +c (Ju1A]mm_eY2ƚX`qk>^{0%)Et:,K0z u~Eݻws^oá^^Zi8zz[*9|AeTk",C>6IQszd"}P m3:PIFꢋ,Fe4r,i 48b{o͇ј%X5S8x;@:j|#?f:Dcٛx<6BGe6qqiKZ!v0 YV,Fh۶AI&U%VMz]Zk y~]æ;988at:e<j1[[[2 Ȱ"GHi%Ǥyypv~*Hˊ:)k =vL[ƌ&V$`Y%eV,,EAtUp]P.)s" V1J\6Ōyj`jIqm|u]6 KJ}cNx ,'Oprr-~!7odwC/05Mtc嘭59JU3|>ǶMed22w}}6X,&gU!Q9_JC~a A_*UBӎi&ͱ䰻kJ$bpE bƋ׼@o dJ&/r9P:qTJC掘Яmhnj¨e:.Hѐ #Q唕BFvo @ZeI+LgJ/$3=f1XB%M]pq~@Ӕen<ܺcomQ+J96Ѭ4+ihᐬ1]^u]|?$R[C WWnZXYsymn÷981^^leYUy {&S#@yi2cJv$ 8Clq' IJv@h4btyIvtj&;lDk\ǧpv:E$Ix| u]nMLU' aTHN\>aZB4=NDQdzu mvhrPf[n4MǏIE9m|`4,+gޠ( $%IK)%B:z溮 njWcc^WyqXgd7gڴVx5Yonmw{&Pxrm?b }t(*dGQDxĚLUJJz0N9==/wynRJfk{Ço:xTJQLrL7סI2lס(Պs)s<(J#^GTd˄2Y2"o,,)Т.\ܔ$YQa5X51?EVh⃄65ZkC0hH%UF{$E|X,Y2Fmxt2!%MUu*8xd9rZ uMIjl!t,sFwVeVZcxԚT䥉 C*n^mo뺮 mjmT~W+_ו)i,4;Kߐ9K,aLMe{h4oubhc6F*kRע+=3*}8<<;7o_O>'r?k%d]FE RՊ45,3MדWf^6k]h{!Ed:bH3Ie\%Q[hJR yQRH$ZC]duaM7- s,,iTER#DiR E H$oqs~zW/sv;re[؎¼ےK+Sc{bxFcL X-Lyv|pBֿ6\ FTmjWIDJyIZ!]ymQN>f08k^Q[EE~PJqttĠ޽{(xyxG}؞\?{c~`4dY^l2W=WӬa<6tmUsi{.N5_Kew4?8|L&ԍI^Kt]nܸaX B6fYѬxAD( %iuł?1կMe` u_SCVԬhl[7+ʲ,M5QҎB|7"fHH-LЩ-% MHuA}n;x<*ue~eqՔTi et-#5mϑR@'s`u$Ew9<>{÷ 9!OM!TgK=?&kg1/iH2v};iʧ~. j?ٿu~ox8~@VVL'̦cTwv:5zhNoUUm> ٶ}q]&7뫴뫛BQZҮ_Bץ IaY3f9F#>c\?nU|`3L8s14@KRH3 u&!: I6x/!ImrZq7Nmwvy1?OC}FW:IsZJ)7o&[c&ej{ȪTM*Z%%Q`Z42xY, ]פe:swz@S<]KZhaFKuUEZ-+V4ZEHÓҤv uytַ? ٽ<$^gxs~KA^x%Pe 6{7oyYYYYq~zt-lCh}IS(3N&Beo&hZШXp6jI뺮7]y6<)7W7W)`BHayZ!A*~u(qqrzz̳/( aIV`ܒj(X&{ bZVueyU^WC)%aڬTՊ(fܺuio裏xz_\F{ ⪹B뚪n6s8ίogR%g&NUaVBg[a;.f5QXRY; ,hy{a@K7\\)&#ڮC溬JeY(tx0c4n%c]R1]&,fKl/Gn_$sqylÇ}6~ܡ5Պ0µwYIs n|Gd46rC75Vhۃ0f4LVt7&jjnju]opSR"٘_7FkIJme!-6ͯ,Kʢj>M.QQ)RJf)^FAܺu۷FO~F6<`k{dJVFJ?ɲ(,[`Y,)?ҶmIZaےN7o[oqrvfUYs0Jh"6S`Y7XQ^MiWMd6D]iD74,kF86%q]MZU2ah qS#m |U=VkV-- ++JaVWTStq y+$e>7ǻg_",ϟQSsS{f6Fӳ]2( s4΍`6 7yCNO/~Zk=xH$aw&Ϟ=KF%%iǡ(9<'cFl0*K"aӣ٢nnb:~~뺮7UɕBQx5%HRXzIUX멬klup]q,3woE{`ֳ kh2`El'!08& 86 eq**ae\NxQH!tŽo/|kO_dS}kڻ{y'SBUT.Uqs&\iDŽ'] XBeQ899FJH!N,k(xkܿ=D+=R;k(OGH-譬x~Xi+gW҂,KR(2-!˝^%B$Ea}9%6]bB1I~o!lmc6yH)L#PxRe95GkP ZYb\OwZ8Bj>!U7؍qy2Z 89q8 !I8<<$3IݗDZ#{}<7f~IC"k0鰳lI`x|X~RΟm88Qbk {qz<_ZJ[sZ2 yu [.YV]uu5Sj[4ٕJ@}"KEN.tzlnos>6ݕ5#{}O`zY|OJZ/a/'.õmn޼1tm)v sN|8KaM(JzQk#c<֊Rr0\qUzqmַ2X]Z֊NWwV6hT/gZ%eBHrSY[E$\Y6=â- K rc ڣ q"UY#G]Pn ONAnkJg} pⴳ&dlX׷v}'%1YFDŽc+ Vłu6=YE +YlmnQqe]`S_*cPV#uY@\E1YgvBDaPB !/uƔٞLcvDŽ#Lc0RPc7Y2@b (e>‚4RI887l N$V"@ (0hOahm| b-rÃcfIū\JBj5R*RE5<)g*<5Wc S~F E4x|k^*y:888booɤZV5a;]^zE2HgE(ܢ;[,8::E\ZQ9RS0Қ˗/nwwJJt>'''!LS޽s=Gǜr(u(ՌS  Ve˳QBܰLp|Ԁ)e$Rhf'ci ןҚHs1`"NkE@H4HiBfHHj.RAa@aJL@h18w׽ ܽ{1I0 Ðv]feV Z0G1*'Wy]NuI)Fysj) :˟VR@`Baȓ"w{iAiI<>,clLxX*,L̼GnXZ ԧ*)@[ "d9Ί-(k1XNE%#qAxRc:Bk?L (@`հ{Wj#A(1B'OՀ>w,XgYZV|R Ddj <ƙ)<1dSXYYa}u`^e:29>2xt6Ôv,8>>d2 dXRc\}!1[,^R.Zބ2. g)%666f "Ipy #񼀣!ԧjrIe dΟ?OEuV*@חYJiFXZL]`; rin@"$ζW7)˗/7oX-o{' фrxxn.NG4h=g"C*l!0( }䑠S4=+Ue1y-4VH FIPZB}'-"3d[ckR5)7yRu^nh؏ ~Vb6x8d>?c2>Azk[+\v^w>1Eo.\B?6'GL&7fҩ B bBhn !JP_e)J9Cq%]|= tE"95yR4JKB?ZwL_)<8K݆ˌAiPK=!uP} 3R 2%5L*XX]]eg{NA3aEEz,O?c8LS>''cmpxpxŵWW{<!%C(:c9 B(A{XJg N ϖ}PObB Ewҗ~ DfBt,Gk B_;r0H뾇Vxyiv)(LRO&c9|J6 ۠ly3;JƧ,p4rk9綶0LGc v]gkllJ <ǽ#g_;+: GCy\kvl|o~}>0L3КEvP01:A"lҧ}&%A( 3O̧(`>xXuK l ( +c2%%&3t;>ݎ9>&ݡEZA+lx!<'Y[޽{]6888瞣׿8O8r|32¨"M~e=Rт^b5JNTP<ۨd(!0F)Pm( <oPQH^Ð -.\>G $3FA6EQ2MG/-U l~ ‡RX)EKJz?#v{-#s@ Af0Wa`(\vaJI`Dg3(╯|s~OZl6#"ry9B_nGL#ԧ>qttDQ3c)YKhu;$YNNo@gX\Fu2ayǬUPS,j.%"]2sK$IB%![L&|?t}'ڥ?[.GWe-Z?*]38]ʉ:fb9L&Z(ǟrsdyGK-=B?y`M?J^GaTx‰Y"ɚLc=h.Z)1.GP] ,U` g>[ȴmJ`>'˜LjB{XڴtB9ŋsrrR*d({{{|y2Oq'%-q*[ E;;;nqJ2OL_ꬲntr{Gn|T57Ey({ ) :cuzY$фxsV`sWnEloou\W"$lmGGǤ!jw6^Y3Ơtx&-6Te%+3C踾 D++0<>"M2988`XQiꂶIIS7GK 6P*#PGfFVDz[kllq&S=rC ".Knmq}(bcc~UV>۷Inp4'FkMÀ7?wNÝ;wyE… ae׾ZJK2#ypkw?ryaR2:SIyRb1D  RzshZۼ!JSJV_6Ծ 4xLڣ%އ<"(%LahޙGAȅs x z.v䖽<'KRfV$;Y "sk rܻw_;8sj)VȓO>ɵkx` ~݇MHSv?%}~1p||ؔ)+vmd))I9T4fٴ2â(eQ^cw`rv+_rp>R|;wp[\}VJi)|66Jr]'ګ^Ieo Ð277HRE]:9: (׫|:\/!ӥeN–LS뮥R;am ż<7GGxdjhp6h1 jڝy.ǟOZ.s8~5vwɲsR97WdY|>w̢8#E-z>J:&Il:wby\4MOflma)5׮]Oшxxq׽oxj G'f -bqXKs>TdY1̵^^rr%dEx<ܐo~u*~.EWIqx|g7tJF\|bmm !#a+pe_c•ElʍB@(&qbZ@)xҕ^{ t柞Jݫ5n?M2(%QBހi2'x-G$rSl 4xLZ~хp.yfʞ"Sz=Ο?19/)y5шܸysPlllPk\v/Ny`ЫJ-1^iO̫)q%Z)R+r5q| N4hԖebV W.Rb4i!YoxgwwgגvaCN^eR̴MY 4 &\~8N H .AOa2,'MΉ~x:14/iFKmB+d(i[\|-N888d2>!+[n< *ܪJYZc;C")IB `㵯{ʼt1s6Cvr]ݻJO=`0 3 cX &财Tu][0^ VX{GIp8v Xbetc+|,snݺ;t:n%V ?tstklmmqtr1Ós#sfY=D%_^ힽ,>Vv jgtjʓNnqs%]K/{./S[\/3⪬؈ L8PQ[8aVb)ӂdT2)Jhrji IDAT‚)Y6׈AKХFH)9_G % \8Dc5/ Q+k.GOȲ,ڠA0Uv(d9KsXۭ 7cZ!KW4S[cUA\G:eعY޽{ܿ_:iɅܾ}g}(`:UuPv$r"9:87~7pkloosyҔ zNrat}66sFGFC`TGw)3RShEY)b,E [0KX<%QR^&x饗8>봘O VUo,(|cs(,%V -2Q+FlQ)xvCۥӴwAb@kr.Ѵz™騄DH5" C$+EʬY=4x{jrzV13 x[>q3L܂jqt4<8770qp1qBcZ硤fssyvѐ=^Oqxoo3R(0R5$Yig?i1ܺy \nW$Dg`0`emlGuB=Y4>e .-N9!cey.ИRG2  XY,m,&B't i]&-%#hJ 0xiRXa0x9tk/,g =VVi/%32Ku3kE)PT2s,] ҲF` (i'AqOw7y4؝шTIwLX,Kx'xի^g>f k' }.\8ɘ^C+Pb^G]cVcKW^eccw\xԄx\/yVʔGyx4)'%f$邻rm܅\8w [qR.Ky<<%vvv贻 9<9CcW#Ё2 ,v=j%4M;[ zz`cc`0[mnNL(JyvCWtmMX,BVų,!Ck)},sZai#{P2&kkڽhA *Ui05˰n>Am5~ ˢ(aj3"3ApdQX}d))Ms,'c1'''LsƓ4#LA7ټ]v]^WmGA੗3'P*gYÇYYY+I| z9ԲIł<&2Ngt%XAKќ<7q^ptvᕮc6̲̀齌ٙY:ZW W++Ab>8?VMJIVT:]gzZ%j[҆f)g؄ TJ9IjCRRޗmci2d; )ji$9P{arWc)PX'V,4UejUVJ;I6'v?ZKn-y,}|_cil1'Y$yAVv;rE;t 4x Z&m p/ 7f+尊ܸcr aX=TUDJI9߫)'1/޺˅ "uCN"]b·?xӛw[B|:sۯE~}_ܽ{/E_O5_ |AB۾xۊ?M_k^Vl^ߟ9? _U/??/IR6ox;xwHg~_/׽Uo[8::_3?x[L&Ow|]=~?/~7_Co dO?x'>/я~ yo}{>nܸ~}ߏk> /roI|~󑏜 |)pt4oqr2gK|˷|#G'?c'~ooGr~ϣYo~ 4҃Z'y??{C}?s&vWG~Wm}//7__/*~~k%VWWoxOwϙ|We )% {?~mMHy7%av(_oݎeGoCM/o=FcF1?C9A'?Ǜ 4_7n|k-w{oswgBԿrGGG\xҥ9fss߇\pc =K7|ß}˿g?{ɿc>Ow{yϱX,^vn/~+?#Lw{}V_b[˻wx۾N͟s}Џ7_;s4hK j{|7|o}h[lns?3lmm~mls}x[[[޽\|;w{ܽ{ {z o]߉D]n鴙 =џw> 4AtlTOvvqItDE޽#88RƒY>eex/myx"66TVrOO7{y#>~38*TVr'ɓG^~y,>~:x<L&̮()yF %K#=}- @.]Z--ͱk^P^^x '2SUǫENNRSw 0pu'+런$FD̜F<  2,N& ޅ8.4tu2..Sa`2^m Y5ʮa%dÆ5߄a#Z7IӦyE( 3g^g+>YyIF>74#({/J]x•+ps{QQ⸴/qo8r$.d"!!EAPb\vDA TQ͛T!77GH/TT<©S"'[+[s/m4~+o5 /OsM9K4:!?/vsH9ŨUUUC__Q8jUl6spV8.+֮] CC^o{iDEcp8022D||t:ѓZ==]"**LFz8z{xYkUW!} 33 #`޼ /O]]ю#anf&fee9~x۠)#=zFWBWDvz[Q,$eeps.^qttCeem/ٶ-?t^^>0]>}Ycm,ݷԴӧD:hi1ttz(lN/ĉv{Wڧ10x[7N6i27A}?DMxT(t'pDxvI8:Tj垕= К f/H3g㥦DM l6 P]mY꣤ܿ_*,===BOOWeС0fH?));ݻ#&fHit MLsB x򇥤-_{q7xo<}7{ g:p^  zK{BB"Q\|ϟ? 篼;w%[Zc׮᡼^^  %Kɨ䠲$xz)$Q~: kX<}{֋'/yki`2 "=HHJ(FĤvrr0z$= ?ݻĤ•}?o puuV{=..X4CEBB ?ԩs$G\\rr`cㄙ3h/Q^phk''Oxx¨QvR ]}}]LT#$dB]| vv2uQw""bеkdggH)}FllR#/ZվY@dnWQq-^AN7k3g1-[zI&F[о |6Q'_GVJູP,B.{N=ASɨA,\KBI٨O&pUl=@ADGE#A^z7_Ad AA "ts!AzuPvEۣ^Uonon'Jgȑb(|Lw3!2r {b5\yzϱa9v\j? {;*tΜ.N2jf>'/-}|aa9Io`Y>zLwu08CY[-]NnY̟7l6 $<Ur*4U(G&)[Q]U-{WW$%l 0i 5m׮]q tI0LrJxjW "Fm 50()؜nY#Fˍ?/_o/@Tt bp܃[ԣSᶣ0z.ZR)++woc7[ֲr!W>0[zÇy( 0n((&`[ AT:lJNnUDmO@ iXdYu兮gq:::x..2j~X]Wӹg 1⸋?_¢ ХKF̙;4~8!m;w!n}+w h6_X4%Ϛq&IDAT1c{.^ G o>OAdZ;k}*5hGBPH0ɲn DҦ-tѐQ#O"'y2]YtU+ek*/@ʖd]MڨpMi ŞSII) {6^ QU]-W_bӧۣzbi`xtܾ}Gnݺup "VSrt, >>Ы!]Ddm`Y())7yKDH{{LϞ=kog Ŝ:ASSs|gcp=&~/|Vqv/3v8Ufpm?a޾j# GO|3=EM OS+W`@D<?hc] ʘ< W{СC+зOƴH[׫^L&lm$_jXNp\ ag !ɓq/m=Y"8(aذ1&&Aj;,,=\.v6HNEƝ&,!)q8ҥ_0e;]mKBEA,h'#_  CMeb$06Lͬ~~$≾.r3֠@Mh]h )K<5  FA/hHO& :* B m?Ad AA t2 ^B ,Cizw3cبF.O[P$gXx MEMpyErlꔗ_ ׭RU\X,SJyE"Rߔn߰?BƟ_^J/Rm(;Wu]~E`*Dݭyn~dYRǺtu#f֭.t6W 3^t PǀAVPpjHE&aԔXēt42j"HkIS?[2j*?&]oЕ9,Ιu#f6x8hiQ[ˇ&eԭ6 hf &"3KN* TSkN"ZuRyEԨ!a.TZQf,T_(lEd/'e.|Ҩ5=? $fp'RIENDB`aqualung-0.9beta11/doc/systray.png0000644000175000001440000002207111107574203014105 00000000000000PNG  IHDR) bKGD pHYs  tIME* IDATx}yTŵ]{f`6f5Kd5l۶P`Atπ~}zTۀF_}vNJc6͘߄8"u{L{R\׵Ѩמd3!uۺ^bʆaF}Q0}_-aƩ툣n F= };x dҠ D2 "0dff)@"PJ!?C}a6WPm1A~])֗F,eR`T%3d(Iʲdi`)%X*}]KNIP,e)UYRՓJw)SYd"%%WJ>/YYE_}~?Vy<3?a f$^Q=֖Gu# "! !RTx<)k'! 2W֌Pu-{V(mküf|Ÿy 4ZvC^D{sBO滀nf{t0}YYʞ‘7~ꥎoKk<_'O?*Ttv7@ R6@$YHу۲!MަOlv~R)YJrvIU1p@3cv< lRX !]- ̎rbVZO[+k0sqc$ THRҔHII,U2%Bp]{!߂$껾!l!#[}1p8 }@K-T#Gbp~БH%"%²PTTTuWzaB"4/S5WXNlL%HIYO!*DU[G" ;s[w8p=׿p8 o+Z10,7Q}].1km#]T`?zW.sБغ; b-iu"&33 0J1PSo bHHi<"tUK 104l36W ~A0B)@$DD /O?,X->zb Kj2Cy<*[ ^}T*7J+`@ivp]GqT6z8Bሺ..ap*!2^0dW! ;m;LEիrC+\},8^Ezf ˲ e;([oUXR!vǐJRMKڭd 4HI&ຮVSmuc1!Of"`)r0e-K ҒR"(,}tICIVqQD"~}V ѧ$ڶ`s Dʽq_R\]M)!Y5#ecAt Z;[VҲrlۼ Gq3r}׸(IqpWV:pi4a v3x VtveEpY>oǟnYg BQQN8?}V̭^ZS9uW;?yN<\pV[- Xx]?_˸E0Ν|cQ5x6o;oϿ^8I9Ls0vwv| z;2Ξ~*zѨ\6/w?W(XS&ŜY1pקu[C༙I_9`yɽxw ^X~OοgDZqk_>JyKݹo:Z/uaca!L&="Hg{))<=mxO׆6Fٿg_㉤ &C1aoa51E“o8 cU0柮A4JʂYJ͗H{x{\qDQ6>#6RĺA=$D  <H_/}ASI,(veT<ǻ' 8X,ᄱe;VV#L!cOص;ƦP!hAG8NtZ;"֌hx9gEߋzP/?B̿엞Τ cq`۫aC_[auF8t\v,F:nH\?{2?QmjsĎ&~]N@A+k#@\agS~}! & A}dM ~)2uSW sC)Md2 ,,3/ BXj>[{ϧ]w*F,6ro_UYoAEկţ(u5AkQq>޽$X`9.,ہpFÄCEYY1P\'G#CXP²nqM":7a4'L% so uW~q f?qâ;H$V7,gYgnod o7vf8::#1GL˻v7۸/wc5HRXj nݘ9YOŎ& Q}'RaӇɻ6]x7ű6pܑ;k)؄v s\7W|᤯_FlifƖmuӾY>\| fU7vw cOսZ^.׹;Gl KECyT򃑎He7L 1-CM@R~!b$0ٸd933,MFse'3=Z@Vw:M'AkաH(gniDUPUCH$0E I 0 $ 8,RODOB/H=@z_)ġ*cQE7ۆ!B ťmnE |!XUE{{ձ&h9^ Fj4'dU2]"R ή1L?,-+ļskҸ1WxΙѝcП8,#HkUn/ڛd\X9ߛK'~ _g2P5]upK2s6 Q%lá c1|>xE8mX=M`bG}hbHhd"tொ cfw!a˅T|;3&uDAGnIKsa*4Ë c CMl e,N 8)YBŚ\_x׿/=%E H}ʎ~!®p"7,<͸nNGNY!r,ؑvwbJbP(**A[fEzQDuWY2hjjf U%GƦ ܠ5'o_D72BzVCk/CkҊy.T`d@Κ{:c.F Ű\s1ͭx/w.EB3Gz[Y\qahՎCkf,}Z^כDZrL8_4r^yM/\zlܸ4l߉*;g*2|Z~R$z 01&2Djcf*RȐ &fbT&Ed0c4{L:w2 t /BaL&DDa% Gy+ <ԙ$4Dqɐj@R9xI(+R(a{a}$ `$`n1z 0q( x;v`&D[:vRp&Azex٫˸rZ Da:FII1qfh mK`Y!>f[7K+T0^4*,>B]x,|ñ_^o >.y3N&JpG2֎5?5߶C0,?laEa@.{Roێ>4&Oo̘+~}ή^| tFcxu ߃g|^}KKѰ}=7:u# KXRĿz@H*:@9G~dW(ɬ?СLnbV<QP!FikPa dD`U,tq+||:~ 6*sadx.,XJIXe($$I|X'raYB$zta3A{/xDVQk$pDIm< tOŐoZww۵š54ᘷnO-m;Үܚ.뮮&m7C:W\GX]E҂!aGWzH[=롱WFja;~p]X=8bx,7!צ[U6lǯ-޴.d2[n~w}1R-wHo>CkxzT Wv_r?[}V*?xH"4v{dvQil1CPR R{i Wԩ4O"j(ŗσU4qM0F'8 bCqS)OgB$'` oC,hԮ?{ p a_.B ?{ivu4գR90F}>`&}|sa;!)QXRbԑ#K`Ccߖ<1|v$㨌Y<_1+'LؾWqS챧=8ּ;k#&cчOƪ] l-xp 8CxGN6xV;kw?' _?0\xUH$uWaeZ?VN^&z_?ϿzCFbGcsÜ~ot^xeENweHA; Lušy7ip"8l +į#Hod/X 3,ȋU߅/bKዎK  _D问QP}ZwDZ9ɞ+@=m XC?y [Y K[RI'oPW?,(1EӁ#yhx֖Vګhmi{<;| wH]⦥ObɲggP1t4]ܹ3 a\XZC!=ߑMSg*8G{-ǼI 0ex; ܷl77/[f`q.LϸVƏaxgt>4L0a cqYӰ'Ky͟ja;F+/ᕌkSK=Subxzm_} ?y>mcİZ\x׺\9%?vH.; *˱e}vْ .1&HPO?lJɁܳqJ&E*y JC]6 =3*M7k%bNrCG`d Qytե{^2FZ:4(tet BxFL*=&^tD&t'PIAB,NI @ --!(pa}]XK](хOaڵ(.)@HxA؜J!i:cw͝q+8xZ1]X*14"hS>ʋQR\\QSgc$~p?Кjl߆ݰ6lB8NɯYpqłUmf៱næy_yn%}pͷsP[=[ڛ`MmæïXÇϼ nsi4'."<|ŒqO1>“ϼ.kց*׿\.g-IixkVs0f[˯_2%A O<<}*>`?d|y ~p9{UO%?<UhjnRzoڛ.,X7S} ҩ4d"%D$`{ViAR3H8שu u6)9"rlG "=.ݤdIөٙcxu—B]g֙L,qD,X~SK)N5zYHfu+Z,J.Ғ "Jfpݐ%A8M?  a Nz_R9OO<[Uu?x<4PZ:Vk֮3$K#6,pPe-]]*=t-;a÷- u0}Fױ <Ԍ1Vl̅e|ͅߋ#}ƛs8F,z!Vl̅"| + ao]XGoSA L*-t@b"$tqx_I i\Y3;gfΞB/{{С\2$d aA: h ?2ĺC&/3:G$$lbMN0a1X!%(ȅɅulTQD}nY ض4t2SR (HlD؅/}ʶ "9\XA.<ח(#|`jXtu|;HYdBUobo/!V: \X*_HȨyo_F/ Y괣jWzRJ e_ s]:niu>DWQX~t @{q |!F4Q$V&_`w ס`"IDAT.qkCBqQҾ !z 3eCP𓶟dvbj[+n;*ﴭ1hz~4 $@'+kAS}\@`  de~M0N+ `n#@ $ϐ2x::vYbJH |6Aĸ>quH 9埄UxH |Adui<@ $)9=FS!LA |b Re}()@EI=`"4@L2~C0ˁH  _~b ;eXG ȿ'ꍵ`eH @ՀR ,ie}q} hIENDB`aqualung-0.9beta11/doc/timer.png0000644000175000001440000001113711107574203013510 00000000000000PNG  IHDRl`*&IDATx]]hUn6-#^ њYJ" j[&J@BmBBTZX)7,hiŖfBTl7nv&5y/3;3{~e3g0㱴$,jj"62øՂ!kJ 2wUk]|>/"$z(J6#U4On <w ,Kd ZT(@8`0bfé zrq'rXxT*d=n{eF[[[( BU@ v] 0CCCX#G)_zόkq\'D"HixLL<@2EQ_1_aɤc^$ ؘ(SSSEAc~ѣ kY:thC5WFFFПXlhh,56 \.p|#elkֺ#D"#Sua@Ӳ,7J1 b?DEQ0ea0yäga:pX,lD"Xlrr̋z^,S֭[M'P*(ꫯjT_^}U`^ qלU^:,vwwqrC+$!eu;!Ƙb{5`pxx|MRM!P<o\v󩿿ƍk׮5X I ՘x2kt:Ai0HE qq tiTXCCCpxnnNϟ?OQT6[Ӡj2huVڡD;\xף NEh}@w,'(BAO #`Fn~:e$yx *w}D;w~ܿ3H {@"{*jey| "z*hٓ{P*a@0`irril̀Cm,˄W6@wAAhTKx<=ûv+n%IJ&L&e2d2ILc$|-pbTzf# dY!L1px^$`DQfp8:::@›i氇c (jddDK0ЂÒn@ӧO/..fUO4######xڰ4p+e@ ٪gEnx}188Hzձ{nULxm߾@8Bg})F}0P*O@Ha|||||i!xo5иjwac2֭[^|Wh Uu0iQ[+7ѰZJ/{2p6D ?HPY7C2A ~ d42L*~&F'ܸq޽{? .|5O⑶ˋ/~gU - H:^z)hs/BjWIQMP3 |ݮ-7,@ o>-g!vYeFmtRY׷cǎ٣G }%C◖X_(۹s^&'N~O?trrRaS/nph\.A .P޾gϞѴfYMSԦM<'Jxjw NYj};v-4q?3gyәW,1 $|gyJxdۀQu͛ǏD"pOAq@ԃl M/a l!@SN;v㸝;w>jq\rebb8qbvvɓ8Qp8 ˢh4zQL(Rd%=\)Jzq!=C _x񡡡'|>0),x0Mӛ7oF裏j:Bh~% &&&,عsg8VIy===,˂DTO4M.1#G欦`("qQq%IZ 4^({g4*+cQV*~zFGGUީ)<dnKRMBp޽D"Q3\*J& R1(Զm [ xrz{P P.D68joo믿c!gPᱱadsss*饥%bH$ D\Çi G}EQDj<' vh}w$PPH$f(.r2LRT:Z^MNN"_"EQ[lcXD+BtcWljXuI5??ϲT*%2Dd2@4(Rd2Qv;䶵/lX\\EO`92>Uy!HRQu6 6 #9(Jؒ$A*|Tpy~aii _ۋ"0FZx@5X_$:ZX3,5Iuɲ_.I|+FK8UM o Ndz. R$ .K;Q k+|͚5}ܹsw8%Nt\Vw-6 /dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ distdir=`$(am__cd) $(distdir) && pwd`; \ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ (cd $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$top_distdir" \ distdir="$$distdir/$$subdir" \ am__remove_distdir=: \ am__skip_length_check=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-exec-am: install-html: install-html-recursive install-info: install-info-recursive install-man: install-pdf: install-pdf-recursive install-ps: install-ps-recursive installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \ install-strip .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am check check-am clean clean-generic ctags \ ctags-recursive distclean distclean-generic distclean-tags \ distdir dvi dvi-am html html-am info info-am install \ install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic pdf pdf-am ps ps-am tags \ tags-recursive uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: aqualung-0.9beta11/skin/dark/0000777000175000001440000000000011331334362013062 500000000000000aqualung-0.9beta11/skin/dark/Makefile.am0000644000175000001440000000012110715346601015030 00000000000000skindir = $(pkgdatadir)/skin/dark skin_DATA = rc *.png EXTRA_DIST = $(skin_DATA) aqualung-0.9beta11/skin/dark/Makefile.in0000644000175000001440000002246411331334252015051 00000000000000# Makefile.in generated by automake 1.10.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # This Makefile.in 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. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = skin/dark DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = SOURCES = DIST_SOURCES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; am__installdirs = "$(DESTDIR)$(skindir)" skinDATA_INSTALL = $(INSTALL_DATA) DATA = $(skin_DATA) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBAVCODEC_CFLAGS = @LIBAVCODEC_CFLAGS@ LIBAVCODEC_LIBS = @LIBAVCODEC_LIBS@ LIBAVFORMAT_CFLAGS = @LIBAVFORMAT_CFLAGS@ LIBAVFORMAT_LIBS = @LIBAVFORMAT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ var = @var@ skindir = $(pkgdatadir)/skin/dark skin_DATA = rc *.png EXTRA_DIST = $(skin_DATA) all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu skin/dark/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu skin/dark/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh install-skinDATA: $(skin_DATA) @$(NORMAL_INSTALL) test -z "$(skindir)" || $(MKDIR_P) "$(DESTDIR)$(skindir)" @list='$(skin_DATA)'; for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ f=$(am__strip_dir) \ echo " $(skinDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(skindir)/$$f'"; \ $(skinDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(skindir)/$$f"; \ done uninstall-skinDATA: @$(NORMAL_UNINSTALL) @list='$(skin_DATA)'; for p in $$list; do \ f=$(am__strip_dir) \ echo " rm -f '$(DESTDIR)$(skindir)/$$f'"; \ rm -f "$(DESTDIR)$(skindir)/$$f"; \ done tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(DATA) installdirs: for dir in "$(DESTDIR)$(skindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-skinDATA install-dvi: install-dvi-am install-exec-am: install-html: install-html-am install-info: install-info-am install-man: install-pdf: install-pdf-am install-ps: install-ps-am installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-skinDATA .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic distclean \ distclean-generic distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-skinDATA install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic pdf pdf-am ps ps-am uninstall \ uninstall-am uninstall-skinDATA # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: aqualung-0.9beta11/skin/dark/rc0000644000175000001440000001756310637164515013352 00000000000000# --- windows style "window" { bg_pixmap[NORMAL] = "" bg_pixmap[PRELIGHT] = "" bg_pixmap[ACTIVE] = "" bg[NORMAL] = { 0.18, 0.18, 0.18 } bg[PRELIGHT] = { 0.18, 0.18, 0.18 } bg[ACTIVE] = { 0.18, 0.18, 0.18 } fg[NORMAL] = { 1.0, 1.0, 1.0 } fg[PRELIGHT] = { 1.0, 1.0, 1.0 } fg[ACTIVE] = { 1.0, 1.0, 1.0 } font_name = "Sans Bold 10" } style "main_window" = "window" { } style "plugin_scrwin" = "window" { bg_pixmap[NORMAL] = "" bg[NORMAL] = { 0.28, 0.28, 0.28 } fg[NORMAL] = { 1.0, 1.0, 1.0 } } widget "*GtkWindow*" style "window" widget "*Dialog*" style "window" widget "*FileSelection*" style "window" widget "*playlist_window*" style "window" widget "*main_window" style "main_window" # --- common widgets style "button" { bg_pixmap[NORMAL] = "btn_bg1.png" bg_pixmap[PRELIGHT] = "btn_bg2.png" bg_pixmap[ACTIVE] = "btn_bg3.png" bg[NORMAL] = { 0.04, 0.07, 0.04 } bg[PRELIGHT] = { 0.14, 0.17, 0.14 } bg[ACTIVE] = { 0.24, 0.27, 0.24 } fg[NORMAL] = { 1.0, 1.0, 1.0 } fg[PRELIGHT] = { 1.0, 1.0, 1.0 } fg[ACTIVE] = { 1.0, 1.0, 1.0 } font_name = "Sans Bold 10" } style "view" { text[NORMAL] = { 0.14, 0.6, 1.0 } text[SELECTED] = { 0.12, 0.56, 1.0 } text[ACTIVE] = { 0.14, 0.6, 1.0 } base[NORMAL] = { 0.04, 0.07, 0.04 } base[SELECTED] = { 0.04, 0.07, 0.3 } base[ACTIVE] = { 0.04, 0.07, 0.15 } fg[NORMAL] = { 0.8, 0.73, 0.8 } fg[SELECTED] = { 0.04, 0.07, 0.04 } } style "scrollbar" { bg_pixmap[NORMAL] = "" bg_pixmap[PRELIGHT] = "" bg_pixmap[ACTIVE] = "" bg[NORMAL] = { 0.09, 0.12, 0.09 } bg[PRELIGHT] = { 0.14, 0.17, 0.14 } bg[ACTIVE] = { 0.24, 0.27, 0.24 } base[NORMAL] = { 1.0, 0.0, 0.0 } base[PRELIGHT] = { 1.0, 0.0, 0.0 } base[ACTIVE] = { 1.0, 0.0, 0.0 } base[SELECTED] = { 1.0, 0.0, 0.0 } base[INSENSITIVE] = { 1.0, 0.0, 0.0 } fg[NORMAL] = { 1.0, 1.0, 0.8 } fg[PRELIGHT] = { 1.0, 1.0, 1.0 } fg[ACTIVE] = { 1.0, 1.0, 1.0 } } style "progressbar" { bg[NORMAL] = { 0.05, 0.0, 0.0 } bg[PRELIGHT] = { 0.35, 0.4, 0.45 } } style "notebook" { bg[NORMAL] = { 0.28, 0.30, 0.28 } bg[PRELIGHT] = { 0.28, 0.30, 0.28 } bg[ACTIVE] = { 0.15, 0.15, 0.15 } } style "entry" = "view" { text[NORMAL] = { 0.0, 0.0, 0.0 } text[SELECTED] = { 1.0, 1.0, 1.0 } text[ACTIVE] = { 0.0, 0.0, 0.0 } base[NORMAL] = { 0.54, 0.57, 0.54 } base[SELECTED] = { 0.14, 0.17, 0.14 } base[ACTIVE] = { 0.14, 0.17, 0.14 } font_name = "Lucida 12" } style "combo_box" { text[NORMAL] = { 1.0, 1.0, 1.0 } text[PRELIGHT] = { 1.0, 1.0, 1.0 } fg[NORMAL] = { 1.0, 1.0, 0.8 } } style "menu" { bg_pixmap[NORMAL] = "" bg_pixmap[PRELIGHT] = "" bg[NORMAL] = { 0.14, 0.17, 0.14 } bg[PRELIGHT] = { 0.24, 0.27, 0.24 } fg[NORMAL] = { 1.0, 1.0, 1.0 } fg[PRELIGHT] = { 1.0, 1.0, 1.0 } text[NORMAL] = { 1.0, 1.0, 1.0 } text[PRELIGHT] = { 1.0, 1.0, 1.0 } font_name = "Sans Bold 10" } style "spin_button" = "button" { text[NORMAL] = { 0.0, 0.0, 0.0 } text[SELECTED] = { 1.0, 1.0, 1.0 } text[ACTIVE] = { 0.0, 0.0, 0.0 } base[NORMAL] = { 0.54, 0.57, 0.54 } base[SELECTED] = { 0.14, 0.17, 0.14 } base[ACTIVE] = { 0.14, 0.17, 0.14 } } style "scale" { bg[NORMAL] = { 0.29, 0.32, 0.35 } bg[PRELIGHT] = { 0.34, 0.37, 0.4 } bg[ACTIVE] = { 0.04, 0.07, 0.1 } bg_pixmap[ACTIVE] = "scale_bg.png" fg[NORMAL] = { 0.18, 0.18, 0.18 } } style "loop_bar" { bg_pixmap[NORMAL] = "" bg[NORMAL] = { 0.1, 0.13, 0.16 } bg[ACTIVE] = { 0.04, 0.07, 0.1 } bg[SELECTED] = { 0.5, 0.5, 0.5 } fg[NORMAL] = { 0.29, 0.32, 0.35 } fg[PRELIGHT] = { 0.34, 0.37, 0.4 } } style "nostyle" { bg_pixmap[NORMAL] = "" bg_pixmap[PRELIGHT] = "" bg_pixmap[ACTIVE] = "" fg[NORMAL] = { 0.0, 0.0, 0.0 } fg[PRELIGHT] = { 0.0, 0.0, 0.0 } fg[ACTIVE] = { 0.0, 0.0, 0.0 } } widget "*ScrolledWindow*" style "scrollbar" widget "*plugin_scrwin*" style "plugin_scrwin" widget "*TreeView*" style "view" widget "*TextView*" style "entry" widget "*List*" style "view" widget "*Notebook*" style "notebook" widget "*Scrollbar*" style "scrollbar" widget "*Separator*" style "scrollbar" widget "*Progress*" style "progressbar" widget "*Menu*" style "menu" widget "*OptionMenu*" style "button" widget "*SpinButton*" style "spin_button" widget "*Scale*" style "scale" widget "*AqualungLoopBar*" style "loop_bar" widget "*Button*" style "button" widget "*GtkEntry*" style "entry" widget "*Combo*" style "combo_box" widget "*nostyle" style "nostyle" # --- checkbutton style "checkbutton" { bg[PRELIGHT] = { 0.23, 0.25, 0.23 } } widget "*check_on_window" style "checkbutton" widget "*check_on_notebook" style "checkbutton" # --- main window style "viewport" { bg[NORMAL] = { 0.18, 0.18, 0.18 } } style "time_viewport" = "viewport" { bg_pixmap[NORMAL] = "time_bg.png" } style "title_viewport" = "viewport" { bg_pixmap[NORMAL] = "title_bg.png" } style "info_viewport" = "title_viewport" { } style "big_timer_label" { fg[NORMAL] = { 0.14 , 0.6, 1.0 } font_name = "Courier 19" } style "small_timer_label" { fg[NORMAL] = { 0.14, 0.6, 1.0 } font_name = "Courier 11" } style "label_title" { fg[NORMAL] = { 0.9, 0.83, 0.9 } font_name = "Sans Bold 12" } style "label_info" { fg[NORMAL] = { 0.14, 0.6, 1.0 } font_name = "Sans 8" } style "scale_pos" = "scale" { GtkScale::slider-length = 31 } style "scale_vol" = "scale_pos" { GtkScale::slider-length = 11 } style "scale_bal" = "scale_pos" { GtkScale::slider-length = 11 } widget "*time_viewport" style "time_viewport" widget "*title_viewport" style "title_viewport" widget "*info_viewport" style "info_viewport" widget "*big_timer_label" style "big_timer_label" widget "*small_timer_label" style "small_timer_label" widget "*label_title" style "label_title" widget "*label_info" style "label_info" widget "*scale_pos" style "scale_pos" widget "*scale_vol" style "scale_vol" widget "*scale_bal" style "scale_bal" # --- music store style "music_tree" = "view" { text[SELECTED] = { 1.0, 0.93, 1.0 } font_name = "Lucida 12" } style "comment_view" = "view" { font_name = "Lucida 10" } widget "*music_tree" style "music_tree" widget "*comment_view" style "comment_view" # --- playlist style "play_list" = "view" { fg[SELECTED] = { 1.0, 0.93, 1.0 } fg[INSENSITIVE] = { 0.14, 0.6, 1.0 } font_name = "Lucida 12" } style "playlist_color" { fg[NORMAL] = { 1.0, 1.0, 1.0 } fg[ACTIVE] = { 1.0, 1.0, 0.8 } fg[SELECTED] = { 1.0, 0.93, 1.0 } fg[INSENSITIVE] = { 0.14, 0.6, 1.0 } } style "playlist_tab_close_button" = "button" { bg_pixmap[NORMAL] = "" bg_pixmap[PRELIGHT] = "" bg_pixmap[ACTIVE] = "" bg[PRELIGHT] = { 0.5, 0.15, 0.18 } bg[ACTIVE] = { 0.30, 0.10, 0.10 } } style "playlist_tab_label" { font_name = "Sans 10" } widget "*play_list" style "play_list" widget "*playlist_color_indicator*" style "playlist_color" widget "*playlist_tab_label*" style "playlist_tab_label" widget "*playlist_tab_close_button*" style "playlist_tab_close_button" # --- plugins style "plugin_name" { font_name = "Lucida Bold 14" } style "plugin_maker" { font_name = "Lucida Bold 12" } style "plugin_bypass_button" = "button" { bg_pixmap[ACTIVE] = "" bg[ACTIVE] = { 1.0, 0.0, 0.0 } fg[NORMAL] = { 1.0, 1.0, 1.0 } fg[PRELIGHT] = { 1.0, 1.0, 1.0 } fg[ACTIVE] = { 1.0, 1.0, 1.0 } } style "plugin_scale" = "scale" { bg_pixmap[ACTIVE] = "" bg[ACTIVE] = { 0.6, 0.6, 0.7 } } style "plugin_toggled" = "button" { bg_pixmap[NORMAL] = "" bg_pixmap[PRELIGHT] = "" bg_pixmap[ACTIVE] = "" bg[NORMAL] = { 0.6, 0.6, 0.7 } bg[PRELIGHT] = { 0.65, 0.65, 0.75 } bg[ACTIVE] = { 0.7, 0.6, 0.6 } } widget "*plugin_name" style "plugin_name" widget "*plugin_maker" style "plugin_maker" widget "*plugin_bypass_button*" style "plugin_bypass_button" widget "*plugin_scale" style "plugin_scale" widget "*plugin_toggled" style "plugin_toggled" # --- mod info list style "samples_instruments_list" { font_name = "Monospace 10" } widget "*samples_instruments_list" style "samples_instruments_list" aqualung-0.9beta11/skin/dark/btn_bg1.png0000644000175000001440000000030710612341733015021 00000000000000PNG  IHDRiPLTE%%%(((,,,111444888===BBBDDDGGG;{bKGDH pHYs  tIME  /IDATc``B t0,`h` @V y:<!@IENDB`aqualung-0.9beta11/skin/dark/btn_bg2.png0000644000175000001440000000030010612341733015013 00000000000000PNG  IHDRiPLTE222555888===@@@DDDHHHOOORRR?bKGDH pHYs  tIME  0G+IDATc``B t0,  ~:)0<&IENDB`aqualung-0.9beta11/skin/dark/btn_bg3.png0000644000175000001440000000030010612341733015014 00000000000000PNG  IHDRiPLTE>>>AAADDDHHHOOORRRUUUYYY\\\VbKGDH pHYs  tIME   +IDATc``B0t` ,`h L9!DXa\_IENDB`aqualung-0.9beta11/skin/dark/next.png0000644000175000001440000000031710612341733014464 00000000000000PNG  IHDR PLTE 333w5jtRNS@fbKGDH pHYs  tIME  8z<^VBZ+u5KiN!)7NSx]k_j?cw|EϘ]eEF)eTmo[Y˖zMxɯ*:Ds$EʎS2?=sJ&"I'Ej.uf^MբZ C^>2c./I7[~S=mDv+Tf()fjk Wid+ W+0,^Y븚X*dkO;FɖhV4HT3+A˭'mH2^ &Jى'ꕽ'Nd6\MRuR_t[^lrϊc~ĉvUcS%^;u]s֝0]Ǡ_jlHׄ]^m|#nը~Bǰ|Jw.9(CXS欶-ۣl(&&GlR|hSy2E#?ެV^XgO4]=n!Tm㎷;ވCo:'lqw %d>bSއm yTiFi7BQ!?b ,*nY(=d{m a؆~t8|$ZEBecz-CNM ԷMf ,ʢjr*g-ӺWYzGs0Uc{W:a 1_TfN*𚇋nD\}:*?]Lܷ`3mRVnj p?DAQYl(tNIGqY XmRPҩs`־%z'DB^~6iMx/Q+9f~]+_P@_) h!ɳ? quJM+eR=JYǬߟ<pўvRߍ^7؞.S!jN %g+U=bY5dMs9*={,IkE7VrhmxHzۥٓ1頄)RxȕJAg~<-mӹ7(wJ9/ؘyv!΢xO=R  ;BE@u"`Ғ)r[ZUB揗3~-kNpTz&1Aغd%edC99RQ!eͤZTTZ˨*ߡ PE=jCf e&UC@ 2P\ЊG`klbJH.n'Uu-hɏ,5'y`P䗿.r \?-IRgO@S?C!&޵⌇ Z+J!ӗTZχ^1G(Ohݙ`=# A7PfbKdTjrgOE){;_XmZ])tL6XJ&mc1⇏D} Bi@B Ez85k,E5bh!4% [ uZ8=WކTV`9_d,A`}t8%}T]dmQzOnݘA)uKSZy.FcA>Asįiy~ͽ@QV-K$H N?}'5: {"}+ kBb:,Ȓ vX#䄝3.FlWp <;}rr?nMVx߿1FQC=ɪi{r>v;$Kb%6@ s IcB}-g8Spu }y 50"^e z)D{^`dbaEjLf7BSG`?Dd*;ޠR 5?MUpBi-o7{ll$zd%-F5B9R+& ۀ'4c5C]ݗUFYD]}Q =Nh&a0r=ra$;D3QKk2#l#o}D*N `sDH6oY"Y ee)5 lF1rRT * R! P硃^ !PᙠĪތ0_[+ۆ9P q ZwMYQjve+D#uJ!"4>$N@'+Tn0ck|"@d!O60p<Y,mQĄEAutkQ%^<҈:J5̾vPa~`Zz,Q}p>I8F_=Hj#怩U4|HtyLBR ikuUhގ4nwD.gr!MAbɦm6`hk^B9z坟 IQDg̅Cn%SI &vY-*aA 6c؊Pj{X[!MRi<@_^A5fk2kNT FiEiGOs "[w 2hϡ9Iy+ژR:THE.'R0٣ Lr/;s KEPV1 1>+*"%cF=V2<#P~QQ@Ȏ_Y, R}_)b+ZہQf=/vHPҁePC_R[F;`jpP[6 c+b8hYY]I(̉m -1[U\SSWC< rS?t!f[M=uޮ ~ 7}(|jU hm =^kmPr%\1rϫPs>1*ʺacOkUh9#uԫ2# }{O`rg[7H@{nv `>VP&*?Q@6Z >[FDwarbvlߐ RV)^- {1,\Rw \ t ٌ$9:B+@Q(9H]_nrV Εd(C۸ty^i_S ME*~g40+Z./л@zr*UQ&[%{5D` Jc33\I8cZ&Qe vE `kxG9يd62PX[ )!*#58+)z%n^- q _tVZH(۶/2<&X 2͗vQM wPnPL-@갗ꌤcD k#&YLL% X!aVZ@ JTM}VЖ7+@earϸgb^n. 5VSϨ(\;{[5¶ol"|[28qeLOhjƿK "}hQӫV\.,r(8H=\,׀{KN^A A2:ͩm:\gcl& mUiDbu+G.oIF_B? Zp$-Mr2qp+J;ްqJ{Bk~ H>0_;=rT\RwtC gD<p{\zpt# C3BpjKط0?p$\vzZK1s]>}BTRT|4Ap{h1bK #Yt?Gi*j1X ¦ױK4Laqێ<@⫒X^=9La.#RF<<͗T8xhZȯ)fp$> F HSpJHh.ȌI9~ZպmPKڷF\p1 I-*ʥvr.R蕀R41-6(G] PI_ !Sx鞶Oz MzNW'e 9ֱ*`ȍBnI +rlCXAiK*qʋ+Xb?!@ <%/?0Wrln)_ʞ xEK,5G.0ëQ&hoz-)Z=$z,Awhѷz;1ޗrU0] \ [7r]}ޅW=A'eчO7_ uV ^oa>z?Ztt =s$;3Skbtߚ|ht-<w C9z}L{ Anj}Ne`9$>u1qk䶂 )9 ,8-'\T%Kg[͂/1Uv7 ֹhSSop4BD;M9~MD{14t8q@ Pi[m6b@˷@\8N$K޿o3r1-Y/=f] bЌw[XWy&ӯG%E\`ğ?`gO]P*DZ @ ty"kLGƴ 'Tzt_k:ʘ3 :?Z5C=wh+uYj&& !Y$E]?R4!=:xyxŔVBdޗt(D ?})O믌6j,]H*'2,L{'RHr1 gCLgK|}:Ζ+PE;@(Aʹo\i.K<3ڹaTP[zʠ^SQ<]T)4B@mӃ &-Cw;S%4-vSTV\8  ~LKn "LvM7:ӘLDu֖GoTǏ{ArPkXB,-7;KjhDJowgA&_ 7lˉpvcyTLHr L <[V 7(a\".FBf`J aFV u9r.d:ex7J J yT)GOmT]um!q`ǟ+NA5l~ި#D| i|C- Վeǫr!0~fOcGJ'S:5-UG(nO0!D#{sƥ)m nI[GE"5)}}J}s,q$plKc[_8 /b&nʓJvu#ynLKyWNE5(2ʰ4ۯ'̧V(gn4}IIDAT+rJܝs(ۻ&}FwUk62C_JtZ0˝J>%۫TjI9=m&$BPv"Wzi`lB(Gz#Q5P&~d y׻fi+QuLaoIGG]ሽ;0$E#+ "1[` 5!;LuCz 5#V}VnD~1|x0.;6"yy)4-v0Pצdȣ)KF.S,6G}&j)O kpmVSϤNSȤ?=i`cյO;yc-䭏3C"dC֦KP6y| r֤Dw7n,xyy,SWKCyQ}탕Oj $1-w[U]E" =qr(V=ojeaW`|QWGl=ˣ+im3_MeQvVRr=oK$$Ŷq)O0PݬnZбD/ػaL xY)ᔬ ~BSb)Wͪp6ݩpG ]A,Tɯy<J];Mm*\(uM9 +lоj) gV{f%ڃx~(׻!UHn,/!Ϋ;B& (7Ȟ #%GNq9)cJŕrRA6EXA\RS1o.Lqy,%5I*n˩_. XS'aKtU]0F !Qw uپ:P]˪2m Ylk=/ 53P Y% 7Kzny=:]n2ak;ًpM24BchJZl_z)v(%u^l}BFF C|ZۓS"?BX>ou>_,1rd b+{$fV'˾nꎆcM:z 8V\ 5Z@tQK)ܡbċTൾCy VT7Ϋ\9B pkԘd- }hU_Tзo0Jht .*C"…5ğߝninٴ(,>.J+IENDB`aqualung-0.9beta11/skin/default/bg3.png0000644000175000001440000002475310612341734014677 00000000000000PNG  IHDRxx5PLTEз˺ѹͶӺηԻϾչֽпֺ׾׻̿տf*bKGDH pHYs  tIME  #: IDATh 㶙ڻv3,\KB.H4CUi8m۵p5v۔<,&-T\fٷYfu}our}r߬iQZz.q?yƜG{-};3xH{z^]r%P"S^ݧT|~><\CGXMHPz[Iʶ9_ +i JAB=<\eg27U7#!.zRxe>ïu~;T+&ad|XG_zFFJZT8 :Ʉndt:N(x|"}]f=ЊFI>[R&(iRd6_P\KI39Wt%|g*uD?TD/71Ix57}1<[8$Ni^L7%\&|8E)JۨY샐NTp\o$B[S=t6/HRǂ''rOh2YLPeI,LV Ox[!Ohw>*3;%_9k0]sg\&it_p6d9? i-QuIR,7(!v[JeBh)6q(53Z._Ry"{ʹ2 i%|s+^CK;B8 L2ǐ 9NUbqd-u"%3SO kӇ$4)4TX<˵[[ybP={("PZ^UEG;5tZ|ItSd Q4,jGME6V݃P)^1$f@e(0:e=~:$S뉔ޫx.2i-QEtbQKU$uCՒ g2ڙ =vWכ* EZ6hHqfd |Ե\s>כti&'vZ A!XK|L6/{ëӛ NQzEW ͩ0>nBtϽ.F`ѧNk,lC0{2P7K{RNRŢ 4&=^ Çn'OM/}74}L4 \R5)1$A7MW/7Gb V|B iNP_Y7 #56/Ʀ@PŖشGa'6FgvRL*-X74v?\~$HHKY_'}VTc׆pJi.Y#ı,[EpE&jЁ`\}Ls^W0UZp|~gÝuF3RB_ރE#դvMZ̞71NHI3Yd,8dCt7Mo1dRϗol W<'B[\xw^$n)޺*Ck[-&m" ǤrkNE)s{MxQIKR+K/&.ʴ@8#svk1w2 c8b:=xMR" sGhz29}ݐ wJ`xHpWon \wZݹ}u I=غŪनp(g'o3]])O=%w< QA TGg礟j O0^?بh58>kVԀ/k_$)+Ѧ47mF]Wky O9*ayGrpVr*"H7q8E'Tn%RPIηSZ6{Zfx3CmJrvckLJ`B!z^ʿhQZj@Tyɵ6a{|pWgAmkhCtU ^1Ʒ9KJ}Q枘8ƇE]-T?uԔO.$ ).V񃂗?ßMk,/tDg· v&% #9luja85DB{TƢȰ^ ğW9Y<9XO޳0̓q8dFO7 ~э]IP%'F44%XLj%H[͚ǯn=v/'#PČm*Vq&UMm \œʻ~RP#a6M%9G{Eٰ|-hprdՋWek/7UID}8$$@\E)2`nUe~d\k[/ g`њIy!\nw O|dde?ɄSٖm;Ulgj1MglO:Pm^A ͲPam!s|{ }s" DиDS `Pw/1G+^+` MWM+!zjtȖ> ^ޥ_\+QđY>PM2~!|>tݶjg@J.Wu_UE+"rִ gTƛ8dmCKHNEܤ/?ɹGލz t+slP%Z%ˠh$<q-i$dQVpPU}~397jz{sZTc3:O1&YEY.w?Lyk-4/DixЇ : || yّ]@.Jr"\@om}ߋQ6rOȷ\e G8vw[ s^k%ж1Lm8hyL!="tj Dfc*l5ɐ':.P ) 1UΑS \-gyӽ|[{SpZP= b;YKgt7n,K tqaDK)R(OmyP.vmwE9sH1%;$Mh?B3>rM'T`$e&_ u(XE Q@`9FNZI7 j^rtNZ#ؠC  *nODBSѝŞ*[,l5= ΂w)]zNB0RDO\ \B$jbi:G$"^&t޿~Lj¹)xq(Nsƛ)0ӠZiXE)yNj\e;PJ܅TXd(I7 gn1jޟyYɃߦjW[Մyh H8E(hhCc@;7 sJmS.g\ǜp.d YT[&M}TjI{]u2w,&f'LjbGEI`~_b&5bjK^ L9X|{LMVE5NƑKfȗׄ26 ?~ G/_}B94U`5v>PX#C[Fh}_)"CYF%/{ZqQ8cKRoEzL}|[spQE Bw"E2&]!dY'$0i>{J\]I?bκE'd);6 U?Ok_fwK,Hs >:vȢhtrnmgG@y&>- R_,]#_׿`<Jҵ@odS.2@9Br^ 'ar\Uߣz :qCؤT+ICJ,fv`+Bi<@qȂ9]w)@[s?VjU߃<_S'] N`"x)r身vuUY\Zvg)TAM5_' %ovԺg $HIy x͉/E@ - 8-)|F4& 3"da8IA gR,J"{.V|oR8Q "zDEwy'~C)TPyhCx\z0I $F0 ϧ/ ^J$hL]7Pb*TEJ=pFDMGJd )21̘ @~u]Ӳy$DMX _v{jj mdN`:Q?wf)i_qf6%ɦix0}ϛl@99 6BI l+6eQ*n^BZNK[ϣLߣ;'>+mHBjE%PDPcUxf{ina3N/ApIw;2"9=a9 7tKIgi.(?)_L4 &p6E3咟pE_[jN+=kZSÄjJb6>çlgܜ jdaDwO"u)gBKFR}`=_ =fMkS2xʲ B7+½w?2Pcv^{TN-7C1?Fnt snOF"]e+AT!]gǏw$ݞ4]쥎/9E^ANMas"dhM#.!\kҽF{}z*E1x!eBSeeK+r|VO#4v"kY";5o$> ۜ,A>eݎ{3!%Vfa! vνL/d"_,w@P$uhza f=,z_JIfN,QYjxih)I<ۚd}e5y AR OTHٞ :ܣOԲ m}lkb[wUgT%g+?v}o876aËlӢ6424_\ <^0 F5|`$UhV0&M=3XUT'􍔈S)p8QLC `ݱpm^н:J@R9FHR`7\$ 'C>݆I!z[799F*A9GXXsLV*Ȁ-΅BX=97/ۭM-EPdad}G$h`C\41d?N*DSݜB{ rz*/k_P:b|vͬWH4'9Y ũgWfžEHuE| *@`o ,gf](+IhjԄs7k'y4Ĭ/LO:B}')Oikj~n5c=WB) 0Iw&)kFiMruWW@tū H_#0+(LXȱ>Us{o.i2TCFX<Ȉ20Ϗ?>O1v:<2Kv,Y5P(6%by g!1~J% r,D6¨>#ׅyACBNihl  '&,] R狙Mk-K6!aUB"݂rǷt[I:ߠ|+~YRUM?!ޏb#Mβp/ݐN/(9$06jϲ5"e"8؝*v `%Ws q U~H/ڱqy{ntя{30qz^*Z*#sC+!]ɗ8bD? .Nt/i( bdHnS#VLM w+}۬63vnlۜv({_=(EFŶA&xJC4zCCXet-=IJdpMEi%P2ʌ ޻\|Yha">#ÄЦ$_eޘ߬[0|nj]u>.ѕE1Ym5ڽfE$Hzx d8 @Cpu{h@$'ڸvB]%% 2>,oԮyZB'^JPrUm2@_ilp"rUDXh5Xq(s\q#u;L0)a Z}xb#J͑/&l0IDAT`͗BUj #ߖ液qŜS?'v=<Ly#«8&ަu8" Uɖ[li& e9%l?%a+ B⸰5cX' q~d/ 0v6ӴC@Ͻ.9@>?*ve ކ6tOFfKTt/& dZ-/?lRz~*y2Z^Cv+bC`WbDU9ۇϟ3rJXh n,,o&3ڭ ʛt8u;+| `{4yc)^o-وoCNe8~ĵjLdiPV3u^ z+~%J(Ź,[((o_6U6|HӉ_n#ɱ_0`߽_DMj&a5e{j]_?XW"fIe넬 LJ Bg'V\$PAuQK9ytҵh{$Lw<ZZ"͏W7c[Zˬ>F?M{'D萢1ܜ4D.7E0!We:-d4MHt9N^PL2,!ٲ-M)2F?O| 0x<_LFO8`s?5jXn+qɪև^G:M/;y`4aSAE/p뙈.~a'du41l?&doAaoQ -އyPE!};;7g"d~~3B^}&, lFuA', H*7 Rm07wF>l^o+PRݴ' 1v:9=ڵ 5Ֆ+JsinU1RfiX`-;U ?3CF٬+ptJZ=+9uא{_)E56knsU'Iuuw)Y2mddE"U8tK8L&EEvׇA|C]_-TI%VAt(LG`4׎96#10w$Iup=<q9Z(weǢj(ٺ{=N]p6+MY0# e&lv]zΠYCslT%“l«M2<:vekke.5;ک$kԐ:"Ų|<]'!dŝy 85F@" .Wf),NY^! xIENDB`aqualung-0.9beta11/skin/default/bg4.png0000644000175000001440000002310710612341734014670 00000000000000PNG  IHDRxxPLTE³öñĴIJŵƶƴǷºȲεɸóжʹĴѷ˺Ÿ̻ƶǹͼǺνοɻϾʽ˾̿NGtJbKGDH pHYs  tIME  "5jw IDATh5{ s)n_GjBA. ơ(mœwvK9{YGp>Vo1$?ew8N릧qҶ$77I2m󘼎nEia<ؘ/Ҕ8a1)mR}=zSJZs-WGՙhi DLަa6RL ɰ ]&x,U;/'w{}28'eRF_I фLMK35|Xꤱb+"=}R" W;iF nZ XByi>(5=>NuZf6&I-¢XC򤝎{jZ֯W Bak'S_פqP!q8OVЪHDcCЙq!W}>0#Mכ5ڳW+ҚҐ<2aQg)Vօ>_;)6q:{VjEeӂ2^h+//gokjjt$F"Yp[Y5?%.3bgZsv/![!XԤtlN #^Difa]n vv ~Ƥ}GMxB>V"3"@^3Zd|w/Xn,%j3Ob39REíe}n6-+6*Kg34"ICuGvAδbG>kj7;^P9Hy WYXA UjK,x6tB w?ۘ/,]̓ WF[A ӦS3^ 7&dA!{IH\KH8"Gr{ˍKf+2Z)֣QnAH>Z1[njQw!U1 cZLjY\6 u&E*<}όIhbɍy~fUK^tf٣ ӧI'`)]BoWmf@.Nhf_n۾]-R1SdBj0Y{ AgϢH/ѫ1U<^۲ W9N͠?b[fPZ <N 4FC=0}iBPVa>nw oO}f5 SiB(mt1~ !^ RVe}LJ EH| jq cD^Wz "J~jqi盎AHf5It+_EÊo5$LG4 Bm {E 5-4,C)\-.2d~ L? ;GM޿|~Loc93K(G>?H!Q_%%2TP>~HdV` ,1i\bUr;'F,  }>H !Af2/˥p!Н`>!VbDbuYonۀ&s`P F $W)hIh#:x@%lmAl39Ok! FBDr$7pOʐpWҴ 5 6hjnP,VR Pב]Bu -tF~6l  i߉pqp =v H ?9ƀkG'x?V5&q8JB EY,E3x\LFF(*)MDS5-U}} *]C rNj@`<uS=)u*>!j{A+SˤPƒ1-_?٘sP25x+k0gNʪ+T:G^(z<h-^6Js4%JFUJZz/Pc4fS}o~9@(t "&6xB$ýVϑM}z9(-Kkg{lqOWT*فq&]y˒>ZFVHOhR5 uƘ lo7PmYQп/"8!qrPF9g*Di~Y}bX*$3*dej#c ah^ؑU ei~[1A9$ͳ bJ ]0nl޾˾f@Hb׶[ E`gmXm* Ӓ[n74,hHGr87Ȓ sX!g`F趾c>g?KX_^,B+w"A}H}xDơkTEwf!4EX3PϪ%E5X.$ sنmvPs{fߠ_4H9I;FE VH4 d:E3@^&Irx.auK bf]P ;x_;g, Ù Sɓ^ 3 :ؖ)m?x!&*] DS+'HOs"巁_~o`gMWghQG-6}@5$҇Qy1 Ac5{J (4qcG4L] Bǂ j{aIl@՚ՏABW;?a>Qk$3m u39 vfӌ@ؤvC!̘[W'FK}{|fϮF*P\9TF"nXAO{oUCO0* >L@KJ$vvlB P3Hzl-o3N|9ո 9B~$R@ =Q} V%מ֋CPH&R8P\mu~JyQH])Am 73l,;`0Dr55] 6S#\Ҭfi WosQ=l^T<:Ӄ.OOp;(֧Rg5ʁ&&,Lr(ЈZ:i&";m\*bsc !VPf%ʾB2#DZ5/}{I,\ $mSc_&ڿ~\%0Gp_q"l|/`#b@”]3dLDcdhG%k>ߵ4l>#i(T #dTa NߌQ" FQOp!L4s+gZM / Ȱ)H!0&xC߇O"n$i^CĞY-W=NdRhwtzn3D}xB:7]+C-ne,]Ei@̭XlL,A4hu[O^WG 4^ p|k_-!Vӟl ;+[P.ĘwG}dؖ~ |/3 cyItD@}@dhieCN$>8^t l 0trӉH\#sTN\-Eߒ S* UÉl\TD낺s;$F6_vGnчd* j"fӵ9 , ًqƃM42^B{[26OhGH NUש+~;jW2~NL3(tZ>Lu/o73k+0C*$0Q4:&TA{iT{Od ݲԱ̡!4A9H I-fwa{:2g3?4=ډ3 2ZR:fgtKA%C/2/߫z\tPh/*lnk ;H][90JRJhPqh% ]%0fmK5CNtB7EfL෡s_Sp"V=!a7v<ژD]6|@EU6%s#=eP=%.=%}1d`*tۣAfT7B(Jo(p3;&`hz Oϰ%}f&3(IF2A8湤sfYxam(>]|QY$h13C,Flw&"|}.SXI(XAS0;u6hA$!oFdA(ƾӳ+cUÏk1t'A)q |O= HeljNA%}F݃m )IZd̂ax ~]C^$G,!1\y]k=B 4=8a(Dl飦p">Lh- ryi\5ο]"^+(-h=!0|:FraH_DPUXGvb(eA±[wTW:g ݁PB7no.!0/{&\=o2x59\Y,QP)t43Rm WoՕ^JY_O X7c#J87Qbw2Wi 4%g*`=PTK u xa3a͝mlN6t4qFUgi$p]inJ|3ħ,u%K]MPg)._$ZLJAB^>̅`0NZ>Fd4<hZr嫵Ni+q:k"?T;BC>E:]$6Qsy6&@!b+r"u`G3i0%3 Κn7CpִY5;ia!Pt /I) 8J"bP.h(Nb}f5:J40tj6 y! bkF R(ڇ՞Or>NӸ{_i(64\z7Q:GOA[88lU0:gOȱJ(DԞi  wPe[69 v?+p8:Ч3"D*3 6p{Os̐nEqHWxAVSqg '_/Lp@Q>5+` ]oڏL&2 ϣdQZ:Eq{IA࡫pUTunf:V.Zq<'?L~߅''AUPAYBjrf;)è|ڹ=TCy~i'g,5M&m&Vf/41ze}QH=(hM4'fݰk{UqᚎUVD lJn`3P[>]~O~_@M33}`![A5Y ]y m\_WS w<pƶퟝirK3@t9`7 v@6c5BMtΤh} sAY&$ ]TUMe4AEwA7-ø¾n<wcy.tD/7t':LC)\د浴ىtάa~sz}atJeN 86LH)bFWjɉt.39( d&^talbRyEV~<1eb%pz5/|OT!6tةK٨Ms-tkz6wgŠ,pڮHȧy!"IDATAexSALa;C``PI@7Qփ?vn=NW.kzg# H ] >'6\h_d`-K$T-jod'Ԡ d].Ѫd00σChAۭv-3l3OȗWR:C4<Ъp5ch Oi@&.utY yEǑECE[q> ?SOtlh3>d]w%ae i 碅釟LEFpg_]fn)#6.* mbF?Wlώt4t2ػysu$o6 .NtDi聸y#4KN)NgPڥ{$PȔ(_I"V֤r,Ai^>M,>(xDt?CN%  y]~ڒC|t W 5cPgG .ڛǒ˻k_Hqהg{d_4`ݨK zdkt康ۖk fMwERM<86nI=.^Y~Ф5]NWU/zMh&5!\6WyMw)և Xsŭ~7~M;OHzB#&9 ^fOwF<P+Ǝ"z\?eA[m ɸ ByX³\P>']aJ4Br}̈́GDmH+YPnC&w4fk>*ÆN7m3TiNB߲Ⱄ0ڿLZ Bi4ږo76,D`"wMɘJG.V6jyk],I¡LWp M6C6XҙnUn[5iIׅ<}@Xg-߶ntٺ|6+W$fEX)pb[;ɮA;]4 A7|^!~0{2ێF_|I}o@'MǖabI)%^3JPets^ݞL/zɴ*!D$` !g$TdmI|YZIENDB`aqualung-0.9beta11/skin/default/bg5.png0000644000175000001440000003035610612341734014675 00000000000000PNG  IHDRxxPLTE¤ääåĦæŦçħƨǨũĨǨũȩĨǩƩȪǩƪɪũȪǫƪɫȪǬǫʪêɫȬǬɫ̭Ȭ˭ʭƬɬŭȭʭƭ̭ȭʭƮɭ̮ˮǭʯʮͭƮɭ̮˯ʯ̰˯ήǰ̰ͯ˯ʰͰɱ̰ϰ˱ΰͰɱ̱ΰͱаɱ̰ϰ˱βͱб̲ϱβѱʲͱб̲ϳβѳг̲ϳҲ˳βѳдϳҳδѳг̴ϳҴѳег̵ҴѴ͵дӵҶѶ͵жӶϵҷҵζѷжӷҷиӶϷҸոѷԸӸϷҹҸոѹԷиӹֹҸոѹԹиӹֹҸѹԹֹҺչԺ׺ӹֹҺջԺ׺ӻֻҺջػԺ׼׺ӻּջػԼ׼ӽּټսػԼ׽ּټսؽڽֽؽԾ׽ڽ־ٽؾ׽ڽ־ٿؾ۾׾ٿؾ׿ڿտ׿c+bKGDH pHYs  tIME  "'I? IDAThEh~e82l`n]ݭ\F3U.=MjPL0#y'+zYH',RLnzb߼+rM odC2gLQ3?H(тsgRs%ٚ1svۣ705(wquk4M"]u,早\Z"Bi?j<3SNn Sw^ߍr(T% vyna֩z2%NjAC!aWӊP)N\iUœH{ڞ\A(Ȃ* Ns!0(Zzpu1"freMFg?]ߖILsU>ge9?{}ˎ?u9[REA-WdTS>1 6p%6+zvu֡hD9YՊfFUQ3(h[|+ :;z봋jY*?uX䊠j X(ʣS(I*\Az~vmYQ/'qMI-{eHulĠ1\.XC[k/"Mk1ܠVb" YnGCi]WŻdV~LCzQ|q [oVYމMhOV;pY+7CA-]DHVmA>eqj!K|y8\a UEQbM(x(u%gN}^g:]ӌq#ׅtCJKL"A( RV ufSUtk3SgsxӽB{ͨ+ޭME!cRFϑz R+׍]b*g9ѥ=_|ˎHo6JYs=H4v-ULq,4W̘oM]Ćw ]뱓Ԍو( \jRWjq y|j u[-[Ѝ,Bcm{]ݶO?񯿏 [bӅFeMc (<_C /u F޽8LHwj=#~{q)re?Y+!QNC}/Jtӧw߬e7 ^CuhL`7bɿ/lw*Ru˲l/Jh#~p>vK{nFT=]dyCs5'p*ed[)_vJ~_u۲>l;=>3~.8ns8.4oE4=M&qg; =RȿA8uJ"Jy j|zgOȶǷu@o&O_,ɫP"]\\$:|{tO80Fŏ}ZAjf\'%?3aw?:f<0^Ci3ok!!d~:&I^cﰌ;bG>G C9369㬊T ΁2:XՋ'a!*#/3c8v/k uӾsʮ,GѰ\^nt@nY0q#6{`GH6Yfin?\K(> ƌoj߶<áۛ7#(i%,zO2%.௝zZWNH r)w)`b, 7Bj PO=UÉ(rPge]Ǥ3p|ɯ̿r#r絊h=)#&9E;<;~mi{m=΍ 㵏):3F/fȞSymm2*Q&ѤWK#^3~Vs UOtϛ2I>LQjɏމf+8$π,-I ?rN45A*e.!.uW8v-w M'S~ BԠy^,;-Aį\ J(|JaZx-kE?wcuڷa oՌO?T$4X>[ ^xNjrsS8>F[-f6-kF >KbE.qS|"pgBOhK:\D/~{/nnBOċXX67#ՔdwK6O5 C#br3ePNCO'\Ȗզ>{?U Ad엣}NDi6P(؏I;8h6_?0b 0rekVzўvH̜ZU"}@D1BιphbӲ!~eYFIw1XQьJ135uݥ9#U!Xf~m89%QIm@SX:zߺH˯mT4^Rh܊j}XFzƐ<4Si.?0!ֱ?m(j嘌'*xi"mUlKTF Ň%>ļ`v`imH~hTkES!l i+3qഏ|gZx-oj~mW]<8 0*z#QhWTl zkUeNi,mD-{ppemrS4!O=,Pmyh:Du/_,I8լ5Mu/K֭!Jf̓$0&̬ %>1 +,D0IּD13qI4ϻZu Jm`2Z(VyK싮"__ܾ[èiFf9_?w4˂pH&w g564!l9nyG}ԄkPp哨,NF WTbUĥWf,q UA2h#k5u狮ljpf VnB LQ0!\ r eܷA]K@nC. CWbI5K>+Kk'A|Ne1=㌚4rӋiM3$!86Ȓ:w?+Ep~Νj@d%OL;, @4]O2hHCk ].AZWX?c"%kEO!{34Ѩ{htwꃸS7 t`'|?3Vnu!ud~[l›"Mj $_kn i2]\&'H1<]tԖ,E|psd :XДElɞͧ 7jrAB`'~f<d]mAu?%ޚ4Uq9&h @ni\|jC$ epyKo[YPiOQN]eHv|^砖|3>ʞ2h|:kVC [sH,W#WQ$Bv[bÍ~_U<ѐEu)(7Ș8us,dgY^@m_} cdHh |{EH4km<# ag - ZЎԋ$30ޑPަ ܊,[o7jn;|ɛـ l ~j]\Ȳ=[OO+Uw_!ލV:"e88a8x}N|׈z 3#kd,_dL1Â5"Mw5o0h-k wUXҿ7ϲDMm}NNȜM3tR ȋ>Lw;F&fk򬶋ؠ~쳋'{0s# ;o.~UA̐2lKhҟMj.ʺ*Z7(H`0huz&g5) {uXϖL(Uۤ*t7<8s2O 4T|ϒK cUthcC5yQ $cyv aX|M|ewN=; m>?Ş޸ԍKk<:rOd~Zs6:~ΈTff$6 š P,Axwn]8D jhX F F,nA6R&?z2{:26'Lܯ¯mQMRi1MF/|I&yv``s?S-x. wWǸ+N&3F8!~~ٸW/{F`/.h1okŮg5%V$cbYFzАK&& |Oβs:p @5MH#O_8hJ3sD%:( 3$3Mp?J"M+jRw8q_̈0/Ϟ;e W' [+FqS꛻3lN٥xftüG'f{r B<3}?db26 tK6W֔W$T-zu֬v{+D]7I4Vi%#cyK4?YcMO[ a 8ÌWLjΊQS |s׾#I^#JY,T$c̙!ĕKOY,}'!zsņjżۇ.]")a  @X}ͯ}kDm -CK;s#K^|| c3U04IsH 朆'A>0НCa03nK}KvEдTLm;l۴!>+[34ǹSд-eG?I:P Q$V> $Q_㼨Г\j5hO]bܸӫc(gqvfO èȃxH^4uO^]l:T&>{l.{){V+bPBrKȇ>uIhiɩ34E[,[nǗ>nvktQz_@Jk`31yH  鉂[e +2 18JRNF@«%˦jQ7}]U͝I/2~~.ܵڗ3=2| 'RE5Mʕ`ϊ~t-}24`b ܮQH0 G2ZD+7ID2*\Z*Q2XsH&@Q">ݠlFᣘb6YasΗԦfk4nr g3R+χ3Kvlq}s7D]+=NS `_1eg+](Rri$HLf7M72NdSͮnO@l1g^mۑe_l憈Hml3Bq9+wӓyz919 |=к}ݾGwŰ9dZpx]E}BeݲmH{'~dS54,v ~7F^÷i- Y5冮ʓ C^} g J.6D"VV=ڪ+eQLliͦ 3X{ddtd;H:7 \MtW|_m"C٨V8L d!JzetkszOE6`19PJJY W k5+&9$fߊy.Wn(A?d?Zs3F,k"gنX54Tn$njȚ /3BWJe䐓Vr]e]AD7줋t5Ζmr7nRa7ʛVA"5*i"ȕ Hl#+`(~}JV 3>(ܼ5v]m p1t" EպYID' O6DӄKM({+o^@M/7QdoBg<_Vfj4yνr767i*LR9Xxu0]KѦݢ M I`Jl./+ U"%lDM8`V;-Eܠ_Oa-=Nz(4^eYC /t d`2MH2ˉArPͳdAaցԅI Iw446~ii.ld<~CbL@>'pf砉# #4dJ!wkT-ʶk{a!{V`gA?c҆%EZa+!1R^eܼћb Z !+<4MB[қZ7~@WT1&0}m@C-IB@"$A v'i_^̧]*l BaSV r*nլ*3eY6!&!Kbr־*m[ֶJ;S vFm{zuB+'|FvYL2d(tYNL_W歂pFq;_,nRۺIiqg!ސv! QK6OO׷P%eUM*g`R~{y&s]Tc}g3AcðaIE]7^#1JoZZy7 W nJb1F 6Q=JY)z1F;d*Q:[:#TmpELNhTbYM[)V0Y݅*_>N߱A `tub Y Y;^-ҴO(vp +of*:Y1YCT!aQ&1'?;vF?* "±dDV-Z* 7}#)_g&(D񳘄k6"'P8Ӑ89'U;$.tgW4cì^%B7[H}\=v7nP[wծwivZO!|4h7Y9x$͐Sa1yB4e'F`%;{f +DŽ%& ?zMpuds,Ře/_r AdsF[zl`l8`kUك5-ʛQޮCKM& A[`6+ ?GBILU,?x 8u)1>ΏCm,x^/nQ*2¥'pܠ乢빁ڒ6|g;<&Q)6wLql2_-H:< Om!Vvϔp_Zuվ 2+vᤖhitWl%=gQҗIG*z`BjQr>ӗ˘yÂؼ;QɃw8_fk<SW wVtIgfi]K ȗҭ_W N7^)Y5h}YR "ɨn!Gyھ-2DުwB$f0t83c&$Q<ᘿ^jUE-\0kw>p ¤ [.nRe;|At+ CHky;0m|2%{K'[=U)IX+b]RJ8YbrE':#ݲk qR[tlPl҆T ]wBx/GSt ';W KM}yu}^Ae UkJq%߇Y^˧Q>r5m2RI.r編"YH{';͈Jm5 zS!=Np̋RVŇ[,>.W1!pT0Uvs<67J,|2&9Τ̓/W[9=G5I6 w_ UoLHtrJ'/wS,n,ˉ`0yCИKvxZZnCxm!6My%S\dP{$QJ`0gb.3Jx|vu8f[)Ƀ))bҕr)SN/OdD7yEKc'sNډkȕg=pŻ ZYr J˂5r̨NE=EݻƉѰdK-Ai,h s^aƅ0(n Yd}.Fˊ1CL\Sj%gg0B簻W!bP$ЬZV_{3 Q'Sݍ(4KHY#tYK*q5~,$5b ./9&rZ=иM+7Ew@}xRgњ2 \ wApƘƹi~hʘ<|Jy-(,*[f"i;-x&zi:2ӚC.ZɕAV1Vmzas4\*_UXnwuQKҗ69G,vU+ جl[AbjD+g4:!FĚ׭&'))ۂauah-r]hLAO`IJgeV֫18i\(ԃrl0RSY@#.jz|YN I؈V/hK!UAr&jVݢj J\\p']jŔP!xt/K%32tZR l1mNώ: u~8},jN#9 KT$Żr``,HiA+xe+Z\It2j #HOh ?o\( FX&,g!L'˺xgsPkD<( Ȉ­[ӄ8=ҚL}-K %se\>%^g;'J[Wl >mGhe!-GDӑ}V.:\\?G=g4Vv{n{Oէ}9w)|]kpa )<2=侺{_MRIcz5 ?@w\銕u.~^fg⾐ XW@37YhgZEh|NXN5RsBk8.@KillɵJ|:_0&bӾӚ0ODpB8jJ(k'fQMfFl[fy™9{<`p Z[M^Qv~#+6mTNYIUW箄ϗt.?2JpLO9g:1Q^xj[" Zh|ۺo|(j+ <J"v8\әj,hl`R ފKrVx|B 2 ޘswf1Jchw ๣WzF tX g:T"?Vm3%(@A6(mۺ8QGMR:t/W3/<Wwɻ3;8VP(m1aAZW&gHqϬVV# dPpf9ϮTc lV+p+ =O VV3]l^$k+3YU y{żzvDDñw&^:Oϸڪ۠ANЛ&JT,Kt\ ]#T3VYP*R^k``PHMEP2Tz<3{,4& %ƞƈm6SJEed&gJ|j +*af ճaʹ"H?b]XbcO˜pX;b8! D4p(6}4=K`OoD^ tz+ u#s_95W vE ||1N ?#~z Q=FPbJh4(*E'g Pn#y~۹΃1I .1񂄎K MBY05H 4YdfRK 8{<p'UC.ӂMtSX2O݅ 6@1/WUS\' rDazE4!LT5t彠Ό#j惂aŽz)mGJugظAǢ,4c(LvmqbT^B5'zZwgҋUR4%3ȷf=r*CvDw *C\C/Hzh>W5~-_t׫l̅]ʼnBM$<6~ |ݩ[k{HΖ3ykNJ$" \ hmu=OR ?W#~?̼#F+nd6 f4uP\ޫrlpL.8~ hYf  htŒ]۾0ak ݟgVX>9谍OLaܠyd0t4Pk=<Uv ClY.ԉޘJ}5 mN̄1#})nE,ʀ|J83PnAV WCVş0H/;d]ڈ`b.@9Pnrњ?wz1T3jX %cfƒ23N1-'4`#"u^cC(s^0 9p ?w\->!ĽKf/U'į xXx pU0~pY=1B.y,B`_B 7 o:ܓ^᳾u؏?Gɥ $=)j)ׁ{ȐlQ^~@(&|Άv6iR:QǿAnüE " AhdDpr~ºQ_C4484ȚT\23(j-V{P/$#f,l7ǚ,u%hꅕ1) =}HD1XSݰ,~lw!blTX榌JF?mشk۝Y^^EGK(- UۡR'vCf^KA\ /u0]f̔֐ *<({4P6횾ߧG5?z ޢ h& 9CaRf]2kMrbnxъ~b5XAA{  2@}Ðl+O\ޮ/d4vjf=Qԏ_PZIGd?d0 Tnnj3s tyib]鵒+4I$[= ?!aYxs İ5).w pFJolr^o h{=U NMP\vOSu4{ m%o@A2(6% ǩ~.htǣ_H3G`>OK Y-Q.P|0jbV+z( ް'j{90(8llaD>yd$p ;ݭו]1[J gY_D mI W`FS $24my&rz, NyMn/EځS7rYCA9s4!Y,bXFo4,hԐBe-=L3A $n"}pap~_%;ovd&FؖQMr/uHg.qxқD4$ҵwr1n̤o;5{́~kOe+^sѡR^*05L.@F$E,9/,G \wA@ۛiǁT@\?*<4DT19_B) ZsIJegȼH$ԉ&!p(J~=Pt>$B+&EΛ>Bx#ժ|R`@RKdb<~ Ɖ0x#3H"T*6 xD0Q۸u*#kod%Ƙ0z[hDKm:B{~.a.z=XZC "M&F0o [~V|>*A5Q,! )s/omY;kxXT,70/ ;V6d 6O0 <sg $x.B=뷇G:W6Ue;a m)"uk̏ xCoU= }x{E:*\Y7STi Svp(.&%.[%I¨q]*"C{KACn~A*:?Kff*Ĩ"DaLCE 11RwdG78ʁ@CAls٢0=0w?Hs'Rq(MtZ"BAq2f'`ko$v۶ӚAe];WhmX׊y*ș^yIC|${ {?+ʂϯBrϵwr`m_hն'\-fxFP|P[FIbL*>|߸*K"ڟ 7Y\;{gqGs?5+Zmt{4@QGAn5R|^id\ DǚK:H.KIB *>\}΂e$'儲&_zW@8 v1k"07Y¥li.a膿@(g~}}4?ag&͏/_҆Do?T'AXy/vX$gJLpsklEf|ubCKI9vt_=E]w 9ηLh<w,*]> @W\m ,K;$&a'IN^dNҐ7qd޾K(W+X/Q+'B2`)Qgp ڶ36,K{vqaݑLQzbwm$fe'~Q miN%۔_C}5Xj7;%U);Sjsd:i&PcǕyQj$|}I?ϛ;ę~УPmm# {M%Fܷkc{NTQ>-f>iϲBNQ29#@nHptdm #);3gʕжrut*m8eU_7 ) ;ﶁ 7Z7%Õ|Xۀ3TjUI2 wz5uq i|5X"`k IDATzq@Cp~(=Ef_7HՁg3bk*vb̦/F4"d <+Y \Q1{Bӹnˀ #S? %H`Hȶʊ&<L/=L el td]sT;-wշQYKrNeQ-a2k= DH|ۄJYtWH.Bo3S`CYF}ABjTc܍PMٗ5 tfÄNi&-ltR=ed^eXa_oF0YS#\CFn?ȵ׿+-Rf3jC;"2)އcdB܆@č Crݗ*T{ahwC.BhwzE(:bnkH|sab۵K0Ep\Кۈ2ҿ/a0]IА0@cۮbJe392S#sա23 mʫ fdƯ=If퐄º$.Jri)Jmk CSCN<2݌a{ nݛX1*mBhݽv&F:[LB>];(׶a2Wm浜ea}lQsG5k]e)3\5kv Xl^a[⸄n($E%.${]#Sہn˺k]%UHڋK@+tFm+hwHXCC{Q5{nTv6RV &4yhNعeUX-+Κ,@z9c0`(as2徶3F3ȀFzЯ B۩@>caX Oz=C۶QVQ }~@mY#-mu(0ѠZÿt$d1Mmlq^PhA.u/=x8s g}CGLwHKps4o_9EWr(ri"3?!b\0 CL`'b+YqZ{f{wIڨt JK;>d&¨δ|u.Sob~;;Y.ZbKGDH pHYs  tIME  %6gVIDAT I [ 4TM& KGȄcƳX؉$N2+ܬoR**8FQ{ѭV.IENDB`aqualung-0.9beta11/skin/metal/bg5.png0000644000175000001440000000162710612341733014351 00000000000000PNG  IHDR[PrPLTEzz{{||}}~~ºûļŽƾǿbKGDH pHYs  tIME  g*IDAT(5;aЄ$1$1֐mHC%%I;u5ys5_rɅs&i~)?c9PR>{wl%I6euYcUV*," 2ϜEf,LII`\8#2̐ 2 I/=|n>J.mVI [iA꩓Zj$JTF*y-/%L(RJ$HB y.<|J XɒLI?߲y~W[3 }^S ߻3Tz*7zMKw}yw1;~maaЙ ;sn03 ٚ0}e372,Wl;D޳8F???~O??}㿽?ooy/?}z__?ݿ|_o?y?y/???ۏۿ|?~_?~~??o~/?|??|?ǯ7??|O_o__o~_O_7?}_|߾Oo_~~?__oۿ?o?|}_?}ݿ}??????_??___yzOI. k%<<üx5j|Z5yr>M dw$aw lczd7ϒW6f.¿dWN.=F:;Iw[*rwEF7K##5̭ڮ6}nGa]4,͹((.jX.s@>p ?\oyMp"O/) 2Enl݌{x.a#oEvtN8\d.67lx2/X  N7®o7чƼ8zq]&{a WXo&Jy3/ܙ̦8j1;ԯҷ~K5 Ul(=7 .yZ[[,jBAVb=+UW UЌVY~S7E3qѫKe-}0MC_&&.r!ㄮM Vf \B!| [|hX_@Qu'yV7kcgTדʡ>񮬅S|RoZy2̇7%ՋY%q%n('GsX#G[w=`F!V2QC=鱿qi-<=Of`YIz}P(8!+^͔CS޺ai5|X M%u7sBqbV#kiʓ.ΡWCS粋b _̓ѵSXM$ǣ^Q +}Ymy}s=Y]/\IAz9e,nr6+OO(\7rr_:8ie=k<ӑuXM/b9T{5-.O9oqnQS\| oPp1GJuNNm9;ZMFd%lz˳ E8;έ>,9հ٬GV\5RqʆJӿ[„KN(#Kh㓂.K&B xXpe-hElw,X.jxm"lO,@h db-zLSugٛ*WeStF&gd7sC4 chshI(iXz ťT(sO|ӛzq)o̯YQu3TbJ"q;ȧd|x&^U)j/f_Tz _ؘ?\,t-&NcE.ױ|7E]sڄ8*OS/fE7u9Ӓ4p$y7\̍E_>Erἢ< ># vķ2STyEbE].Ҹ-s7sˢ)j%Yb^H'>q:ҥ0x^VEx jG')O_ קNfܡNx>#iJ/RW v]Ui- Mg=>r/zS@ROȷI߹..x1`zcHV = .X梥B?M ڬM7BpL{vCE6asn橨,M/cE. -ekU|0Mn@ܟG,3% 2 eo&|ܡ/x5( ͚aH7{Eп'/ϔɂ6sdŊ)d)sR'uQrԖM*؜*s<_v}|/7YXɒ#w 93Mܡn22OSU䃁,kP3[XW3_oqŴ%YkU4慎¦Fو9H6'80B58CWa- vdr8aty@ y%d\_ꓑs &Iss5pEM1'ySoC^ܟ,2lA0I0o!!-,.7ks 'AeImQ%Lz)*ŧufƐZߝ|p9¦pYPMg05Ndu?Vn*%<Γ:|~꯿gsyunֳr $e=zX\rS"m8|.hKͣM}avLg>g_MeqhL&!') *69K2bLșp&i|,NYfr񹴜WĴ}=e߬OcG\oV[7tN3wa bġ)&<#w.1[L^aE/U & p+uiaɔELٛ4Ww$fգ#~r!RiJW.?4'Hq8f9]kx-uĥk'\`ЗkY K_Bm]!W7ΦDCSLIXzq:\j9IG/y$Y:af.xQ<;H?y0NɝCӾL4!wfY\L$sOHNL8/7MS8/5~wrɸ{f3Iz# KQSdbil@ > ;>lW13-$g"Ko "Ѯbt07|dZ4Y1?=6ԃnl [P¹` gJM<-U•_Ṛ[ '9(L0j'\ۻ8u8䁗Ba. 3'In5U8!7!e+J vM7L^u0Yxc#n֢Sut9bJ*Op̥E.DSl29:,apX\s'K6qޮj&N + 5!m͜GKRbe%,=fCSZdj~,p]8/8PK>b$wؿq~c xI> |DŬٜŵZ ui/U~ܣ,)cq*9jId”9 Z^!!#L,>G2T8yXwXFrU H) "%C?=T2;ɛHdg欙qwq;$Ai(,LQ:a10=䗜LTK%ani|5iR`SMs82ФF'bه4q$E5 0O&s+0ԃ4̆|R䴒vwʵJm^y }|_sPEZ.3%X'<q3`0'w|:R! >M>iR]ԅ/x8\^,3h|%wWA]p>!U!8X%[i^R!7C6^5E(+肇EY02&eH*sMzkbLSWDo)y,r.Sۗe7g[WR:0&I%и)4s+ٮT.x. r˥EbSuqPѱ&J'sy1WrSwUK LZ$Hq2,G@ŞHMӮxvrQ'pܕy\'2vqb5`1@ )J?\Q2tvT$R'VJ΢>Qm O(h  Y|&_l>Kyeo`YK>*s@2t,@p7R+\S#|!Yẜ#E.}͹̇ugbm\jYdg/<-jxOxM31+x*0ݙsy^9$ӹ(e_(e>XP'}݆=9 B9P 벮l^Nʹфqf.<&*f4֓iVkчo۲^9~V攜~?Sl=P',0 P:5&Tv2`p P04NMxI'T*O/<k2U0dUACdI<9SyR֩yyݱ_9f:$l9R?8OgSq9LkL7LSa>)ar,S¢ԅ0+.NZgJzj;ЍwqNr5vv醁gyo#9J>j~oʰ (qJf4$d\c]4<Яo;(O2Z\a̜;2a]P 7yk~u6bȴ'p:Sy,ߘ/,[9]gvzif_/y䦂<*,]@h." Aq)y)&\͹xĊlDo/pE_X#c53L]>aztÒ.Oe`A..k+^%7U'Y%#Y=L/'ƾ<_PKjSL^n(N8fcaع=) /MM8e8#f=[}Jo!ǎPc-;YfSU-OqqRqNl%f )jIɣ`ot87<`m=Șdd쫺lWo, 0 f,7D9lY#oe&1P{':{d 13Ԃ/RUι2WK>)yo x7;]xy$rW:fPH?}Oh=N2frU9`B@VrRp9ѓ(;U=yO I:*\ǯsJVΪ>4^ ɼۡ_++~ONB|#O-POrccNI3$Y=lDǥyIAI2e?e'r |lr⯢JN4@o-.yӼ2K[FŹk.Bxpbty~EWѲ5L07}\ps TC<1 ,`nzʷߍv1* 1LWWNG >Cռ=*9Hh" [{\Xym/UԦG:՟Њ!ŵ^sKې%%/`:53](f*P$N\V ւ7y.{;|g)<yR0'~c88(Pᐠ2Զ, `>+&vB*Fc/ Ys]V$ZeIKIVzr`TK=eI=^.8vn"[U:ou}GɦOU= H}G@nvQvaSj̓KkXedUns31jc\,楇X3nKӽF+s~#t]!7X0׎oYKk10žs>^!3Cc"I:Ä ĜMtQ`%3Ҧ^0+ G-!f1ԘsGkP- ^zP7`!ɛG*7UW.~Xd'IAXa;^;``ۅɔkKǩ̋nRd *<٤yat>b0iubC/dwXUhN,RM ldA3gɃ7cYp((C)|f;S 7iD=$)NLa 3)'9ؓ=ӇLdZ&h׼Sܩ]09?~60CaC6i6]5a Ǵ c.hX 6Q觖tIK#e * j!ϴɓNYcx\rۭ*!J@=8cMΛ| z<\̕~~`'WsUB;~r7+L1/ד3[G ňWd6l-6> 3Hr ,x`mw%a-N%߰i(0K%2 6) 4֋Z*GIYp{Kep4>NyM-$,6GwScU6/xkфMn2n͝*am|2T+Ƥ5@v1̋y +^̦^NsqC84O Ł9IÝ$IN(LHU,w;^ }S'V&kL! >bJ5o+a?saH5s^)k&чF" ̋4Ħ-0BfUbol4Źf޴&ORxzUl ǖc$'lf/ۥ͍'Ñ6-F| WN}#G^OXLX:Ehhdw N_ 3P_,C{=.&vY`v⃏o" K7k5/|{ȇ`[o&ɷԳH9 ΋?C6< ^h9Mo3䂃g*Ɩ8i+2pNG&,b=81> }/=D?8,_.3\& rXiAg_T&;PLYr'3GMY` ~)7 >Y~jAn-6^B^ܱoXbQ242Oׅ5^.v1Xaׯq1L=Cj."GU(x醱js"IF 60xĐf >8e 51edsr: eJopR"d 1^J!J&iݘo$^X6Ii^ A岅¨–DA *Kt&yCÀ/"=J!Ǻ27']9m!k X+>=IEŨ!sYYOWI1%Vy>؛BN\2 4 .ꍳܞG9Ȣ.&aBPy&E74 TcrX9p 4v$M?Hjl$gxIEl r5Y7?OQU ,g䥦U Y 7|am<@QYCcG˼ˁ2*=ࢷSS A+:$mox؇BCu, 7+ ^g\s!?Ǔ՟a4'gGz\x:fҦZPBUH'7tv>jO_k!U%5-eTY|UyZG"{s|X\6V1m< Lt'e$!y|PRݤ)*[iUl8\&Y3<.{2vAUks-bpxBhɘh\g+=irB|+*eǫrIIb+܋*(`C }Aa ,8dLx:L!AB$;$znsf{^YE⹽h<; ^p_3>r64<  8h=£!xƘ4>j`1P^ )h! ݤ3sU}^EY؇Ut3Xbχ >ńs+B%P2RtSK:аd|&M>y^ j1<.8gH'BC㕂 Lxh.ӵjI5m\QK-2&@΁{j'ƈ$pp2CcV$Z(и E aɀl\$rۅE6e^2֛)l|8r_@5౨4Um%lE)y>|**}JaLP2D蒂+hҝH?p<s"Xh՞z28l^No8wʺHwC%B֞ܛy>U?r=jszŁ]uIC1Gn,t& s[ٸ!ᆅ_!"O2RZ"C#qOK\|(RqYV;0qUAKPNV|))j8 p^+jye^Mj8Cz SCmfL8) /S*I"i9TFHȐ& 29Ō|i@aNy)©TN*[gc3ï:g<3^@yZT/ K, HJU%O8 }99$'>R@ݡ)r&L띄=ĠK=ԁ2(Cr'@'s1  lb?$ݦ`cD[#I3?ICB_r>y[u9I_?㲆ٜs*sA bq9GWYim>X4ԇ:R yIQZ G0¥Q"ka/ ڡ.TS yuH?Mɹ(Lx3-LZdrBξ؟/+iL脥tqvxNg=t9\23LnLׇ}\QCpsBF" F( IB J$ C+IJ4'5jy#04^ZT9ǎs d8۹LpUUIb6.r̐!X  y0xE"OT dp` e"4lźXʹBMisRuz2+[,?Sy̥NVWW6bC=䢓.>Mg?6 aa3'@C6STmk_푂~P f2&1LrÁ\\2$MDd҇+ԭrYs['NqNKNU{SD@LIJ%.a.Ƽ2GL"I" M mt8 s@@0EVmɁ3- ph7}^2pN%c>zcǵ,1EU8C]IkAi.)*ٜr@3Ep8^Wf94t  P7|f.A*f!(.*ݙ+>ؠ'^+IBh +Hdrem"|I#m/fP~U~ iRRF-18pc3U1+o쌶Cl93t]ZV_Un Hr;|iLyS9cWa҈ٓx =<+s[ý@@e ?yh]` *7SdqF= F&LhiHEbp*&Ef 9U]E9X{NgI۹Ra E9XRt3Vh5$O8w,vlj Bȁ­Ȓ@!0:(H%2. C+\:!$ W3f.,MUK׋-GrŋNFe-c{3Ik5ZًhRq< ]쓽ݏ3s52s UwvN8dEYR8D.$DfbH xN =N ݌dkrtr\%!iJ_c~,s@% b.tw ~Y;kOAS!j·T沞-?q EsC}ћoG9D`QV>HK@[\$_d#hK6DnhGFVJ !1 O!$de*bh|RLEUbdoē`5CiԝYp0R@՘Mv(:dFs98V8/e}Ǹg1~V<.>M쏽q`a\hhmoO)dEX cG44 KI{ NRC<Ѕ>*/0M0q\8!oisb><-ALI׀ y b0A8/-dȇz6Tԓ,և3X7/8?E?Lwb;!)k2 .ΦF%'uLbie2m/<5 0i CäP1CIC(.GR5侊dBp>9hɏBeJ<0 !w?[:XRԂрBedK%u mkKӡƴ, fG_w:58aan3YdoאT/L u rU FlМCM'ss&7Jy[O12YC] vΕz#7χtg lݳ~mU %҃E}3075⌽_#;Rb!AM(ː Ҥ@&4(W2, qaɌ#T%aJS: m&uK3\ PZ>r+fm>/3 'ᡃjWΘm fl|HquR >=+S#gYoAP>xj.z7rZo#rIm5vԖC 5Xl'tLq[ ~PC5,JSu֛, JrSv:xa*-y  W2tBhȇ\!:ơZ\e5lυTa5;#@0]bIL0Ѯ~qnavY 6=ͼ`wΝ=I]ӷ,>s0!$'e>ogWjߩ7SDT<+ gI$~ o<gsIZ~#'՚1Okp6d6 4) n({Id@p!Z!TG0%1) ;6pRh1UXU#pd  Q7NJ YNf,CNd=7+3(z7Ɍ#E?β~' ys_sᘳ9  8q0ϸxbuI ?=.{{j\s}1~pQOm%࢑79N}9Vg`PI}z7s J B !B S@\OLB$U$@.l\4()*̅XIg_Ȥ&4: BB|  x\Vrb.0LdF0\ HpȁcL}%Li1ޡ ;2HΔ/C*Rwwjx}!||45"h50+nBHrPo^|tpe>Y 4@(xf@ER"EG\T*aɲZz1M ac O8+U4iTJNBBdp1e @`cLah+3)oc1 B0O\ZjzlU9Vk$t9T[ʺ䧼t 'oP O̡ߓ>e<+x'2$'@(5ԝ&4Ԕգ%c\|!? d!B_d0|PM*귚,0pz*.WюsrQ1$6femI*eLF7ID022t3JBdXPţeC*ȁJʖ%т'$"8åC+z035)88',=Fh(|á.ɝׁǙpEW!IuK^_W` a4 ,c*"6Z4=  ZU9C};:_;9g<0n޿pn^<?Lęt:s~dƋ@pMybuOWjYpҏum9!sa9/ *"զAT8 6PÜmu;Q朐(J6Ea(@ @*'@Pˑ` 0ɤG0 ȘQ#ok`lηuuIᖖVjɅ/˜YW K|NX*yghUg:TߞIz.&.bBq^/jby;Ih98 KujflH",8E_bHq _PrQ3:ȳ͑ &sda/HaS #naEyʦBıđk0 ]ZMB ,`)aT[/6:5Pؘ!PnB.chjVnk'c?kpesU<<ۯ[Ӧ-lWGX7Iw 5 WWa-V]qsSpak.jYGc&(@e:/jqcv`tKO4Mgoh;R/oLXSR}s7.* `sJ$e-`3Z0Pr(`VK0–5΄e/p[-\'#}Ayva<\9t恰>|65_^r}j߭Z_Ņguf~~AymźXƂX0"lX uj0E+?Pr _BMpm/>*Ӕx<{]6j(+Te.=򱏹cOU/ '?fj[hh&X%&ؔA88Ɯ1EFЋG1yNS.s1#alkpeQ7|UU7KCvw̡UuS^ VQky^ W/w5+QPu,8temv[˼2m6wu!LIyS JlX!;V4reΪ«@e=*ph=l8ЂW8 - s8C: HB)T2I"A Z)pN EW52-̲YPw̸j)oK^dDcIŗR<~:X_=L_^:Z/p=x a8MsQ7uxo>p ]mQ.=%붶U)kA[);:\!C.\Nm뛈l/HΐK̦,wfn#UvX6:J0C/vr.3OBRpL>I C Id@_j/p_lIf.>g9Pf`?^וiDzˡOF?0iX!N&N"$ ;ePm&0˿wtRdB} X( c+d|)s͇’AFdb`+" z[ p]T*8o@תI]I{iJ 7{y/ҙ&zp!c}M _՜&(]r*sC{=ޗ1997u8 gpWG_^x-mZ 0,1 nGE E&d !)< %D1L߭)+iAB he4$P&$ 1a3aYxp647 6:xW 'u1_YPI|o7À7.2p}eBI YC0o&$\/;< IX 3KjX? b 'T4`)3sq<W|>̅SULYɋj=uYx.)coYVyƽ䱫4+f0jz|[Dۊ’GJC8F/ a$ı!`44 bB$`&Q$ TTJf'gpV3Wċs!PIȓI|œ<'Sgd^:|&#cfrl$VztkS9ܥҟWf9ȋ% ;>wr>̡?IsL.&|/Ja^]ajIMbi9I:pb/| 0_L9ǧ c!#:RTC6 5*L'CiC%RPp.Or0#;(S`6C"V8eN*t;/.H<$ !u]PH+e}pLJش;X9\#>0psSi3>g0ǹrvVymx5M)&T2"ü$9zs^MvK-M2^p͎6y;u@~W1L"yx>ppe> K斱AljCQ]vȂBɐrZ+ٞ&ڔTUHcBD-0ΟPlijET0I↢&a>As"7^v oܗбp.SͽdnK>X>\EǬ2E԰;27P+7I9)vW"#츓>:Xau>ρk*]dಏ'󍅤a 34,*̡ga*9"F8q<D@1(xU1c-QD)-a{ *Ȣ\zч P;+9.2fz[d1I3w'sR`7 )P nJ*~ʟחCW.E-Gb5cW8MKָ9U9\Cu6;y& $ 0+nt5΂ɍ.7 M&䋃s^ɶ^x˰>wlF/cH>o+O!?Ye^kD'/vnid~92Ih9?a+ rr"ی|ÌM$Nr&]N2v悹cþX"MަȢFx \1P7j<ݿz-jfj[e!/M _^TX#/a-PTs 7_ Ryn%lޛSl!qN^tr7g!*oY*ϥOR'O'g81&zEGaF[\Вa~_快vT+rZ$n )n-^Np7h)f1X!<-*fȋKF'Fg[rK5\x_;9U6 X7O/W&^9RP e@=Mns;>rCp"/x/) 2El݌{x.a/";\:'E.u2b6, 'VQaI.̈́Nn0>y88o'WC ??%s~P 3X/ً/n^%l(\΅7dWN.=a^u؝yӝ\œ%sȳ`;E h袶ײz_W?%Œ)XKofi„…U.;2NJ=`e6,,=a pE/)7lm!nX[M5G^UU~{r9>p7+I~O}N5iׇ2a<.[eb6Tȗ25|8j1;G}m %/kk͢&d))<3˾xXi?aVNfZ/VȋWeWZ޺ae5X< !@I=˜!'f1]4U^tq~*"oS.)0/FNa5KQ _+us~6lm?\/Vy y:[a~|-^* K<(OsX#G[w=`F!V=2.֡^ؿgf ̋7yOoJgbޤpTQ>(ꐊ^^eա)M?_7'(Z}g "%C/w V/Hi)֋/ rm7gD|Ɉ̰MW>/xvҺH gByS0Wzs~ 1C~.w 4Ty!c ,j5|6zf'z낲pX@i꘸us/zrUV1%I.jdrL??!^vYTs Ed3^̇)y 7s )]Zط*UdP=@> ;\''9C9c.x3z10] :=ɁXu/_|˯|W0Xio6#C10oKfМْc6>p0}ywNjD # vį2STyEbE]M iܖO{CE6as楨,N/ӱm5s HK' z|䡡 $~,32M?oE~XbO ^qM~ʺxЬNXwYA Rz-g|̸֛Cp}0FҔ?y㺪ZLwj}) )zǗgw|S%<9C6lVY_ݮ) ࢋ2-e*Uf\fl  eGfyAob 7Y8p\ܸY .JxڲISB@`RekϏN/}Jyo6*VC=dCK kq답}uK }[8SӜY\ XŬdòa[sr6gԋx~t?t_6Oȇ "Oheis.m-(A]D %58lw5 !/i q55dâXTemN0,MU2祾̘F+?7N1/uqlnr8o9udMr|ok@9ab~?a>_qŴ%Y*coe6dM)'63p Pa~_r|Ze CB'M7f~Xȓs?F&\$98)!6ŜPynwFU)/vnM7/0CMI.f$OY,je~W:&E=8EѢR3.G G9t]Dv] R%0|7.0̞k׻jdo2?Þ7=YwFϩ8KBd-曭k)N)fAa/^p+sʴ>42"ߨ;CwC9r̒ly G'5׽q69~hXn`^LQ+#'D~S>f0e  sq3)ySe,fzUS>pkjfES6werO=.8!)z:c7Sy>C}I,r.y"m8,hK̦~1;c+ʼLg~O?MeqގhL&ғV *Sv6A{9^r?~ԯWl )!y/Jr(:4niD/Tâ4^eFo }O9c‘K|a:cO[6|M7nxQ GiKx_іm'3 /$'f+,K~v=r{~w|ye.w,6>k gN &9f-z8UI!}".3\ TyGc.-rdџdNunbqϛ,N + 5!m|LT;mkK5 =_W+^X9fy9ȃ?D9vZN9 9\Er2C&lSe39n^"ekDSBo/f f]XY^ތ|>}%LV{.S7sUy*wJlS5@q7db-oK^2rOY7KkqRd1)PWfr9uŁ"2/ ;C<;^)Mb[~xqƦԒ/*UUDI3H;߬"abHP\ް%%;@|TˉSEJK xyT2;ɗHagn /6ii%9Y\ko> @39sCuxaULþB}C?fc+32pn~800.u67󒤂ThzI9ԕlW*uo%A^hQlj.J8:ւÄSd2s%/P804ّa"!\9w@ŞHMӮx* 'pԼ?2+rIΏsQPQ@>,ד~nCNXxHuYW!l61rx4vv\ OI .rX0|ږcs/)9m9 XU:TKgg 8֗^)+aܞ"Dy=+=\xD9UX+^5X-KlպbzSҬ^(>&Un)f1+x*0?? [wu,q6IAaôƄ]}d MdZ R¬8k9?)GC7r:dXfY>q..w~~9qo&|Fη. hLI}K*,]@h." Aq)pHbE6bG|/y mun˪EMϵj_0I!_,jq42,7. i$M;) ٩6eXe! 7% ) Y cqb=ۘ9UEw1a]P /yֵj?x&P Np*b+cj34Uy ~qsjתXc_ϟf%x]E&bS(XXE;4VᥩgĬU/R>1cjeba9l ]n.lƎKsb&x5%%w’ @R_!ۺE0C݉PZAˁMđ*΢dbBX!.u6]kdf)+1,R\E7,ypy*}ortqx@N)J8ww\^_}M^QJ  }BauR /6sLKƂ UuXzHDO sTYP.?tÖ590U6kㄪ50T<ἓg2bof7U*\Jj=/~]c԰nXdq-k;\ônۼXRgY4߈S  h(8pf^.ytb1ù0 uA.Ϧ2b቗^`N_<~χw4IUCy%C.[{sI=[??xFt\G u'l1ǼÍ'r lr_JN4@_-.~ʇ|cҖ:Eq^Z(𡋐%Ϭ_[>PX~*J Txgq,tARI`җZꢆ:l8[Tpi"jQU.Xev1\aR@Y^d(<\.SnfS8pqo)K3) yƉY!7XTs7cu[%8me-`a^g۝W .ט/{)P \Oપ`~8R5yC >1ɡ<MdFz[ǎp;m3VUUm*zsB>rX1{+O]^*P|E`Fu6 A9Ea-MtQ`+'hS0 -9γ1$0/r]hy %z )LtNųbfMԺC qV0BsÞ̘>dm&2A9oOvu3T莿&/7C3xlV⍗' +f`'l)rY͉|?Oh< 0pqax )זSnRd *<٤nd<>7t?:96H+so>!:b,F&akyFd^fAמP?aa CЗ@F ^k@R2 0U-,:r(fRsd^x3ἹdEwj;Jɾ>Λpl_s]>& t t5z&laу8G?ZؗF:4Tn j!ɇNYK^>Z%9dBہ3|o ;Cjp1Wn(1N2s?X/Me6~ocRL/y yH\Xb68U `Ci?AjS-sX97I^5 3۝P(Xoǽ%K֘N!?L10]k| txscmw%a-N%i(0K%2 6) {i{4 ‘hqU8+&7)sCA1Hrjs]|g\=5v)XukEESHJ0\80z,kuUɂy_=[ mv.&G*`_}rJ%l1 ɦ c#UY`[e6-UdR?遛9/K롴fQ] õ @DoF" C`S$Yu[^- r^,;7i|ǩ;=^6´rGhmb.m^<;l4@=go/n}x7.:,Za-d"q6I7XyhRYTD́foz!He~Ra7| nsUt \f~E7W;kSMYź91 /=AcԬj#VRgpƛ1)lSJ_p%0or𐖢`1 c}݁7}M6g`~9Xw\2XM M"`vogs{{m"ao%G/sENu[^B&Cn<LĸCHK7CRR(nE١&Y$.!P۵d+D z1ɳr~!m96s2"=`>r~e€-5ox,8+Pe@1/f1?\5e@';ST_/M^-6^B^_XwVivr{m 3W㺰9q" I?M4sc?wz9l͆/fM5. V8NML".&`AC7Քs4(M%&p`¡Tpad˜\1H^ :>*Jz}ٓCd oEBhH hvӇ]z3t#9ᐲ Ӹ`䂦^hy_R$lm>93ґ9}9Yɉ_0~W=3?·~8dGdz`.gsd>˝tsMJdBu{lT!M7NU@a 7S!jx`e7| o;x9vXc![̠5fj!a&+ѐ*?T0P!7,"d ne]j!mȐa,zr ?#BXa.r 9$lLR0rw,/fԠo -?oX9'eB\t1;^廓o憘M Vv!W& @a'ް醱js"IF 60xĐf BuM u7fXN!LkN X a!KkbC|9Cu{fv{#J.Z:|`j64d/ݓ~r'JNY 5-SyZo͈&0!rBۄ#f"p9rs'[ȝթC O=ܲ?ӿ$a{;K"fo; |7幬#XeA~c^\ 8gnܞ;WXdQP{0!R(<٤膦!*' @ _KbMRke$8#-ȋd:9vc~@37DzBue^8r ۖCp1n+?H$bMqƹ,?J'ldS噬/Nc ׇ G\?i")WSuzg/X^*+1 Lw9sMs(Xfʒ͌լH̉&)sTbXM IaAPr-s見ޡ\psg"}Np`8<蕄LKMi@l¸;kB|g>CWy|b^ @e.Z/n hvaXs*(%m2RfRK!vMvLY!hwƬr9ȎIW`b2$l $EZz~1CuqdDeIiI]~_ҡo(fP[8y%7* UUxP8L tz0m4aùKNXx\d;o79 +<>ùǹR!;P$(R%>DAp` ZFlӓwr; t|Imi怱+O{CBr3efz-9xigB-uY},IZ{cmۉJ.//<6h7XGZ\-6,&« 4f:<g" _%rX[3C\Wp.xO\s!!qIN&Lc*3zN1hh,&dR`2raueeQf,M]F-EGd 21/PDZ层L͟ `G\~̱{[c5SE> Re#T9# 'h/jJ-Hm+4>j,Ҙ("Dd]$D}YF4BZZ& T:٤4 ,+">^owjU'?a4'g;k`.7?YhkȐժGR,9fj>Q\t1:f̭! 1?$$t!77U_MN`S92ɺXᾨuX_V͵XU \__1ua)J-xJsAKZu'gQe9 AܰLL0a9́ 7I>p}\C=FrDžr q xbm`lŭ _w;\k ^['wpb9nDB5N$&Zh1&ƛ,N`6l&sƀXH Ά[IO!e^EY؇Ut3Xb od1 4tI$ X:%:k裋"/裡􅇾~2dәH%!2VH94т;qܼ9z,Hc4jk}KaH/oFvse^7ɡjTMRBݡ)r^&L띄=ĠK=ԁ2(C^r7@'s1  lb$/ݦ`cD[#I3Ox yIK̏Ut\ 3'@ (X˜eaeAId/粗iAh(&C>7XG%4"EY/\N4.23VBT]~. +[6\՛Nr9;Etqv=d5$E{rbRe3LnL>.!9n|kI#넄$R!mf!qNbY<@/ @`-o~+s<C5.k |9 ^pQ]eiYygi:R HQZ|#W0¥Q"5@Pit)|X:$ُ}S<9 oy& Y˔LNL`3褋_z1 aoaggN,l& T־#7)|P f2&1LrÁ\\2$MDd҇+ԭrYs[O8\ҥ*v.zUE3diVE^() ޺u*X>ٔM?7J<z}cǵ,*N.z餵 lI9ŁzԢfx8o+ s،DX$  !$8 9\@ѿ~JYcH. 3/ewa76J{'WM!1%))84H92i苨',7-Tt8V` tᄖo,a1Yr$P2k 6a7SVb/@)9z*\|`o(F͞|mûr8ǽ5 dYf K ~%-2N]6: p陷aGSG8~'ݰ+3\԰'l o̡Oxg 'O=3$u 0,Yx)f+ŀ D u sa4ly!tۜMMaC!2Ącf]z4 ~ lϋbbq2!A$/mஓ(ujL) ՞_(j .HuE&oHT'H0+ΦZ+Ě170a&̶vN8gЩ5>K%CDBMd. Y?]̆d8C7#ٚ!C.z EZ㒐b/5ߖ9UEdؒń\V|1 ^̡䐏x t ! #K4Fg#ʸƇ OtCH`ɋNAf\X"Ny}1[[ 3Ik5yr 48.י~NV:}p_}0p{%s(V:'}͹_hcĶ{X0)ʖ ~HQrng8)סnHYhf_XNh@ P1Mȕvv oET'~e8, & 4>di+2x3Ĩ%sH^[o. |\)Ξ+db;LSFC64sMi|t<;[^"H|}BVՐ)=T-߿q EsC}ћoG9D`QVW%-XfT/2H12ң QU$/-a xuLłs e.`\):r|MJp{=W:AX^P,=XWz9 sS/z!Ye?S/!)Ԅ i9q^!M$lI3H.PKZ0Z( yɱN8mmi:Ԙւ%!^cڌKJzyƗ]8L2?mF6^ Z>ޕnABhsSxd=To>5r̝Ud 5OW풙Ijw/wanѫ6!Dv^^SlMm.?PcZv"KPu=TâԸ?9=U7QMhɲ0M$z1E`m¸ܒJ%Ò A9R)LUd;A3@FN`R43e0 %ih(#b2:x:)8}gkɖwQߩ=ZL7 L* ~U)J*ZɖC7vyL&R? ׍G|smїл,n{Yۊkȗt<5xHȩҵ).9KB. tU㊳ 9:80b5x!271$hDHI) yt+A ƴ/Ej8c@!ԘCm͑:x#〭F/s(!fdǁ{/Fi֋bV=ʊa602E;8 N(7f^c T7 k=1V7\^ZP?%8$gxéT[8ۺ`dɳ^Uy`r glR֐bF4&P:~UL3 rd{KoxpBDSM43 <hrt2Xd3PZGC_֑O2:2٦C=h3(Te>.ft; ȟgi/4e"%H%xH}<ss G˪Plͼs!Oꚾer- $9)y;{RN"R^I8&VN'3Hx{0>8#N8֌y2Xۄ'IIQ'fp3>F mO2I TS  ' vXhBn"  #rY04O",$j9pEpPTհ=SML8؎D5tqWZ&3F«O\8lFN@g4C .N3"ޤXOr?ԛs5K^L~g#Y|M $I%r~3xpް+Eː0zM.jp JL^M}2#HICGqidb^!E=ăFxN:YEC'U;0()-4 3L pC>3 !T+c'@qѠX0.cI$M.Γ:M #`32J8U2(Z*X6#%,Eݙ9h%EBLPr2ɌaC66[HLá(kTL~%L{ A|55"h50+nBHrPo^|tpe>Y 4@(xf@ER"EG\T*aɲZz1M ac O8+U4iTɤ&4: BB|  x\Vrb.0LdF0\ HpȁcL}%Li1ޡ ;2HΔ/C*RWwjx}!|WOZvϳL~2+xNrR/ RCirHCMQ=z*_2~7@2L| EZTx©~¡ l*rX90 S@kc&_vDRFdhΐ*4mLYn80P8DZ8` Bq .ELg`ڡ"[U ]2խꖲ.-)o|2 )(鿥[(r'^PiIDCax?e8PW]G1ط??L-֗,T6~*yơ2?Xvq{B&n*lٓ]MA$&@(Rɂ>`(!V&Ppd"HR&C&n@IX, xPRL}U9XSR$ZPSgtH#CC%pQb1gC |o8TE7:8<<OIǮ4WEI[_O-:~S9_*NMW}iX%&/g(Se\x,W‚lX007#&MXzܝ\qbdȦ( 8) 0U 1H`hX殔%BrJ0dP4T@Nz0'%̨P5IB"` Ď/r${I-f;OE:'9M='zq7Z|ٹ;շK%$ELP ^Ul?o8ם8I-Du.xV[M̗ Z1֕[ 8NYJ8*"pSY9P9Rd`4, CItR9,f\H&u8"5pa@Eƌb7E 4,}[KWe u8K RK. |\̺/q4:+r8wxx_lM[X/o<'&Ԝ:<4\]u~X M5*R ) Z'GNq`@&t)jZ6 h4 5\0uSmt3/@ac&@-j ]uZ_mZxhV%/?/]{Zu3U? 6b]vS]cA,M6`X uj0E+?Pr _BMpm/>*Ӕx<{]6j(+Te.=򱏹cOU/ 'LXSR}s7.* `sJ$e-`3Z0Pr(`VK0–5΄e/p[-\'#}Ayva<\9t恰>|65_^r}j_ZʚUxU~(XUY:ef^/kZi󰱿P )dLꏔΛLxeoWUm|$e IIK.sV^r,Qqۜ $Gaـ,LIḩf2Nt3I-4l4rll Gc΁"#E<҇ X9ȑte5ܲ>têKv*_ҥȡK;uOPCq}im?nÂUZ::78.ֶ(Òu[*㵠Y.zYnwY._6M[$gHץefSE ;f37*P,k{ %;9'!)r8JMG! ܆p2$B%#$bat)p]$pU#c,uʌRDEn@48֮]|+˫Uue] ÍgQ?0/֋8WE@EBBS{nWR\WJX/R? ]>!jPt*-ahṲº>v)p\ovY sQ[/'FrLXG$$vК O(1@2Z(7l 즇;7,6ӤmBVCTlX, D:tg-ͽ̢r}An.᫈Ա2}50t`zDGJzȆ$&s !8:D&DLܤ@3D`J, j ?ؐxqu[>j! y2;iုx$wL>KdD|LbJzcjri2XTC 0TrE:h.qb0y)bPb$cα)B 4DŽ*'.+T[0E 'Pa?`AӛdS7=IԊ`H EM|C78?SH%&B${$mxyS); 'G9PɄ)  4`0LBhKQJ .lb )^!C-|.O;Ēe.#^CBaU`s)ܝ򖼹苳wrl)|X7pWQų`*so;^^qB%EUuY|o<<;!Wk;ds*b~SC 'd3ڄ9'=ny2/|3Z&_JV~õ?X^pB8+L( eXGN>;+9.2fz[d1I3w'sR4$~TX?//!|]Z擭׋ k>z q U q_?a˖JC\;S ,29)3J'l?a?*~+'S狽n+,“4\7il7uJ2i2o82`DS FLg#H%'c"4v#+զE3v]ifFJƗ#/'nYUnn&/kٟÖ́uBd9+.<^"<[Db}qON5tpj~;;Qk{yȐs&p>9.^A7l3bJI3N7 :¶ʙt9;Ie " b 4y"hs@ڪ`XEw b9?ݺcU֟*uF OfM]Y 7Eܙ&!Ä|qp׫" or8s3R`ϟ:St|ry_SXnC u=r_>ro66뛽arsiI:SpN9\YdR G!8R, ik`ƦpQі8E=aذẸ0Cmۺ?嵣2iPzk ~E6L xj]f KAjS1/֭{s-=$IӋN0õX'| 4Ǻe5 -̏^eYi*Js)>CO,Τbot1Eʳ .WȲU|cS\^/v@oaR_*8y~Q75\/ot+up%GoO-Roj-[chh#%d"WG^hcM@MJX?˾UחWs;.<p]y'2/EСS\lIRe7GFֶo5Yu{".?ϟ~o__~}󇟟?Ͽ>oϯ<ϯx~O/x>痟ϯ=?>~}>|oO_??|?=OϿ~}_zoy_?/{?<ߞox~oϯ</?/_/?=_ϯ=>o>ϯ\_~g8z=+v c-e^j)=7I|ʌҷI=ݽ\吘[-Z9]q>qe^C-)xY1˴+&5c#Q^jzsKz(Q1/DQmVˌ< u3ևCyVe>R˺1ebj@^jagŖ6[f%oVjEDw8YYud+5۬m/M[h&) iy[2_䐙JOUKzYw|f?2PL9fˑ=jr/ uKmH[唹;n5)Y:R\1!+yp٪^ٟRk2̦,:\e.32` %G}d3ua3RҌL5ltKc_&Q cJ"˾՛0FY.9^RoPKJߠwrOViô3^q xS"/8/:Od쬲Jbydq7uqћV[]R˴mbuۗ.YYϿzlgc.9e).mbFz_zȇ5yXm/3T6X1ߤͭvE;t|x{p Q1یe؆l3e,KnjVJⴽ̑1ۣSR7V..Sy7(-0P%dR c/n!/ݦ09]^Œ\d{7IRK]ܔ{&uQC}x]r1cŔ2B~)ΛUKmaCI]*\X֛FIQ[tcBkXK}`\dMl}DjK]X1Y\znY4з,iÅ1URwsTT7_*f$qZͶ,slY:c_E<11JGfQDy(VmZ/isRz[KLQ4/y%bEQWؼ%ұ^2mb]w/liub3R)Q|S>چkٷ\έ1Αo50֧K^Ù\0&TRq.2~M]iCBP-ikCTYfqƋ,U>H؊zh)kd%nU4eno,}V%a7sKr-jfIɇ*ټS[ސ}.ćjը"ĵws˥.o M,uo|2||pmoy(V(x\KJOj2O2κ\7u=ys_ַ3ͭ9ju[ћL4/U^m^|@:Α7u i3j3nbfYEk^Rf%.sIj룏C]Vϙ\m2*>Rŭ9vly튃X򐑭Iz~Yzݹ.)e-+<%e6GۼL,&5:M,iW]41cZӗU|RO޿%:Α;ƴMM$ѷYNyo}ȼ/L;!֘1/seX9,.8GJ&G v*rGf1zmn+>.sԖNZ9j똣irsXqls[K~~x;RMT?^g;2/3GRc_:Gך8$]^NgJ֨dzsK--PG.sc2vo2c@JEk]RniZśV˄eosgd3jo]}ָESV1#e&GnN *H1YG_wz~5}\՝fԃFޠ,sĿc2G^K.=әy-1Y[$^cO2i%;VN*RrFGδl]^'oE-& [OjC1̨mJ-E"VqTw,y 3 wgn]ܪ԰eA/s k R%UGҕU-[WWG'g%73 ёcz~ʹ~UIWsA7s%[uC M㰶Ȣ+s:]L\9/3wWeRs$=ݩK[TLĜV9megԣ˚8rQD0۔e!7D2/b8&Ŷ"c 7K9j\šRCg:98Z#nvȖwRf%+udI=r;D/˴z3'˺_epu$”גS15&1m>{뒓9vv$lWc^JMu5`S5<\|ʒp͚.}tR)0t1ĝlE5f6.0*Y*bwfԸ-CXщ;tڔdN2I|d]՘>>brW#99x.39#)i5wSU3JofүɎ)9rϲs,}iY1d0CI z;*m=h)2x#r[X_̉LKc\=˹%j3J+#ْ5\zs˒Rw=9> uenU:f$*sS0ŒfY%cT+H#S-܃a]\:3pOGgT˔U1#e33cfιHq2YKrFnM\VKRWVe_dܥ~ %6sX*)R[=fL!z8 ûަ[rŰR[%cD˰ZJ3aKSzY>"Th%JћcF)4f e-Y iEItKF\K:31-WNe,qҙtjGFz撝kȘiG=ܪVe⥣KDȸ!m]k=yΉ7=+9ߙȱj]vP۴y%,40V9#͖eDmsqcX~Hmٙ[tmVwuRÖQmL)ճasylv5n"T4)n}2(֘z鶖9m-)^2qPۜLٙTfYS[EMv yL%gRJɕp/a> P[^ʹYf]q|xbz痟pT鋕b^\)SBi9rQy67mr5V̛^0enͧT%K^Z۩d1Ї[/87[GbaȢ<C%yIHU=B=8,}KW&0ojEȲJ ,Y1nyέ8MȒnzsh&HL&$ʼK#ȥ9;*Flu ~,oVT>ZϿh\6=ptƒ;11Q{3'{2;e]pJ"Բ^Nɦ fKq=-oKǜIR_2QpV]ˌ ,ָeʢsIz:cs\]?mmehfY[b6[.զ؂Qc1#1 )[FFoVSD\P,ae1l2@-\lmެ6G>X>m޲nr%c=iBhI*jfadRoɆ)5q59tCF#kt$6|K+U5,ȞjZcIbd1fŋ곒c-SV)fa\/yIUnQIr:' ".֜aGfKdrbsEH8Ą6iVAH66moZ52G11nYLvrKl,Uzdd~/axXvT9^֡M󯿪HHM#dqj3cldá$N"s82pY3'rOd LeQJE/UR[BfRgm֪Ն+2EFї>2fbk˾eOYҝYWjƉ~MR;9[E>FZ[ƌVo.5Cl0r6/`K d%ǵyHKYZrem9c/b.y$M}-e>Zϟ1G-e(iJ(`̕TKT)r׬5bⓙIXڼ2+[fϴܙQGnyĨ1R "͛y1Q͖*|R/gb(˜wm·ZևXLJiY4/kCFt."fIŨrXK*DX*ڔ:Nm"G,uXҷ\r1N!j ,7/r4󿤆ȒJ.gz~y蛋59˴9Dv*Yxf3g|JY!NKA-N=gty$gwg$s*1:=2.盹b`k]\%<2:C}]jh+>s0݊faɱʔin!ͤ-ZM*zTAVcmFZ%%nWfLmLڬ[W ?A KdtE#{a`P * sJv{JۻdžۻwWUHn)U%Bɵ>ͭ:om~ms~p͝(Y_t5#!ؘ+#s/YV$P~c?2vd]IqMmy$Ok;67ˮ\Ր)m)JS*jxɣ 5ğiuUT˸ô9R}bZ+#}fKU:M"$Oj7țl:ϺNMR}ɎO%-WDWrԩ\^ٿ4]$䓳mI'fo|3KMootLjmG){dͫpܕixx#mqingWW$s%1KXIR;c{+#vnٜ2v^yL6ؒ²_הYYF-{YK _Ou-֬DU*Yu"Gƾ'k^{6H'w7kc'rYkmdoy6}L6vevrWˮNdҙwS7?$?ߕ5ë'3*?PFdW*oZ:4}(Bc_9"#c֯Ke†7G|n7NldS -TQ2uW:vY)e1D<âħQ<2Hɵ?b?ɵGOVޯ.o^1|W&kw]5f쥒a;;en+MLԮݪMztV\vL&$\K=uxSQyJorⵗֱl;r,{JW_Y.#Ƭ.!|d:cV*Jy<_ukJФcA"W~U%̫Zٱ؅|t5d%fLMqbܫ6i)=Ux{77&jbXH5#6fwlxKX"I"FW-V{*Q#W4lۤ$%'657U[?ě:\"cݴe1Gņ_ӱw^y<ԛݒ^M#(H(f}lsmILHě&21?|ƵḤ0kSk_=NM*IQ[$Q/WJI_yU#T}q7{Kٯ=iהaUeWHª+cN~2wxw[6]#hw)Y Q%mɲex$/gkk5eORʲisx/em+eW^^YeՏkiq/We$fS[ؖ>62)i6nK;˘U1_#eNFry#TlWw;RD2 {^I6 +#enmGڽv{)M$8*6ب#}WlWŎ*CWVk<kQf+y%J[S)~mju%+ %|^4gWf9?pL(X*}iJn-[?։^3JqGRBEcV*ﯴ:_3꘯ ?~<;n;e=WAnakX.M^%c2Wȓ I١ݫ^;{زvFIHUM?ٓn=vx~9I]kcZ]Z̕R!{nE'-0+|r/]Ҍ3n+m2e%F}_篽MDzPW:z$:cKhUѯĎ>{lezǻ1e(dH덬7$ꨵ#׌\]|$TTfd\ȕ2}fۼ#.W_ؒG\:旣]D%)ZRW36jcZ.[chY{UPc]JV_RJ[vERӯɐI\3SޕHTULH{ȥT-Y[{U&v_[ֽ1?FQY'zm)s5}^JuGƍʯc{=GUc^i{@Ŏ)~kIٰc./q#>j՗KTHKTӲ\U;,%e.s:Uz洗aȆ3_[I?kإ 1ڵ1r1$ʮ,KG>Lvmd~Pv(5\Zٚ,`9H֬nkVTHW;ݫBG]U<\ֳQzT WYcWҖayFzrcki&&Z5f,;p?]t/nͪw])9*5cM1T5+9~t'wVٛd#BU%eid%+7ړf*U1Q|7%k*eJ&ڮafk]SIp+Ru7r֯YF*nγݩ}s>H7smy#tˏ{2 [McXkW7GUId<[IEVq'{NIv<̘T??n}2;t>vM&Z$cc͕pY:ȗ:eKGJuKm>U2[rm[v!fQki{i3זZo\b'qO{w/v#eld|jld~iyl˯]C\0,bFڲ(b^FQů=kK=OJ2jU,5D!m W/ZlW at]trXR8܍vHbU}2:ϚRIl6!ra]Ǽs}eGat״>.YU #\x~b0`_Nů HS1/Jª$'KO>U7:7]-)7kn#1_Fѱ tL׌*{]6%W"c9mMPķl5Z]3e׽ 6ovlPTHHJM"чCTGi"CBږyGbdTl,VFaq~h{!-cǎ\ڵҴHW%I9$xٓ*5e 8ʶ-ۮ}̵'S-; F+5G'f<\*6sӻΒH 뎉}zymkF.KLҽyGZaݯ$q#kGofC+,!Xrd|+=Re?D^}e#$r%5}aCG\ѡv(YjccNMqN^u:sDiux1]'}mu=;u|# j& Z HFʨvԶ$zZ9ȇ8'f>h{vŒ VG 3,xd #G^y#h KH D1qϑheM =!F:ļ:꧗y9q1.5㻖50wbkF w Vw䕕&3^&y2TQZK׮VPZsmG<'Kڏ|3Fz$Ο)WDAAa~:&G˲j@^g&ucdp崇Õ 뮭e=yJE75ѿþ cR{+`fa9[_7/ǭKu4i LD"ǖq_{/e.E{e:u٫o(d_!QǼJBcgK/uקnW͓i| TZmO{{NhNYJܫIߛsJW֑3{ec_}ub6H WI+GnSwj]fl ݫn[fݥ2:IA{rLImIr:rFV32NGƮjt#Jdq_Ddپ*I;ɫ9ɔGk.URǮ<4'>J1>ɓHs8G>y*GcS*vGV":裯SFILH9|ڛ3; ^묲=A1׾}25}ɶ˘K5d/QwyבTNƹ!(l qkJrLYJu)u#GV\Fr7WkGYQMGjvLJTfҥ+c롣+2PmxRq>\}V mMڅ&KhT7*j-"K-V4֯Wܤ~$ɻ=L9YW}2{=o}y+\ezdd%봑%7I'H'd:x_yaKDK81cV#_rqxPV# :mlD<|s",9}5#c+Ͷŷْ;ȩI*xO{j5ی34I(vFr~қMίSH#!Sw=#߼77Yc_y"~ˑj̤w#ٚc[s]EteUm%7{G!]L:2v]gMl͘ձ|֌fcW*,7f<ꑱkT?Y8-^b01]ml9y S ;IW˫oV>ZU9fgh"G~'7';NO՝y3O'yQs^_k呯+; ]oM+iH#rDjKV+#c{k|֐صjHd4M V~$dM4ZT^χ1coα֐k Wkc>? <Ԕ͐4%YБ#i:+a~,iɼmJV&@Mߺ:oOLr99uM#5hT?fJ}yͱ)OWwڕWx$l4_Fr\'Θ({}73m"$Yt&mc^s͏pa^cǽU%dܣLǖ^ƾBe5nRsj \ ,cr(eq'ѯ+mG&Lº6}3I>mo\S^I[-]uw;+ۼ橕oN趙9!!ܜ&?4G敚8ެJ9R!8WFԾ.5?И/G0kp:GG9]{onT+#cK 引$Ʉf&hl+M+J@jR9Z{[Jt`5]IvoMru;<򦿩}ӜxWn{j]{|^{lL%֝L[O|52эϓi:YdyFБasHנ2T~q<lq1r}c͐hflrr@V9G/Ufq+91J_m7{קso[';o7x˷F}s{Y+*9-rVʹZ{U kٕՑG^YkBϟoT4X*8Ga:Ѵ#JHy\ 0jd/*#+v4R[!@MbM6i[YYZ9_L~̓vSƘW>$é<4MMc+\UcJy8'5_{xV(w +`_>i~ҿfһ*kwg$7|B*4 q&=2D귙nФf7^e"C1jLG(Fκ?N%1HJ;GW,Ha-Ēчq4Zδ6 FrIE݉ѩ/I#4KcNv#I~eh: 6y}?/o? F̉1HfuH\tlG~twH)Osڿ5|zD^lH.qNcѴ'pL7'7Y9o$c6^y죴K#[omҙ GnODN塔iKf6$+گHol%LN^EIJMRf&$7<#/N'9hnLޞy<6O\:>:'3{O_=v;W!;l鯟|9R;KA>d1fFvwh?ɚ^I/8#Ӝ1٤^TCf.מTL@fIHdݘLTۜ@enƚۉθ61sҼzfBtѤ1.Ɍ6"ímv'Y_cy5t\ C,?tdF?=\yǤ}WѸm9뜔Oo3)Lnd4o6ov&oWR]Id5LaM餿Sr24MY&_hf[ 9Jed{oУmPk=ΊJR4Ӷ( uUIЀ:&:mH43*LI$ inHZ)i+E7(N[-4?z=4[[g>ڜ?&ߚL$Ϭdb&fh0?cMW|skz_ ,2$& ɾz6['~&|2O\aryRi癏b~QMl63&uNr0?soOgh:KB~r~3~꩜tSDdL8՟LI>:ɏ}We?4g9:#5\I99L9*ݮ6Y̵"΂>/J.]m?-S.okN.0R[fdTKGEJ(4e1#9e޺3_fLT Qy_wTd]z&'YTM$a68:!%$LK1eJBeXÐQiٲȢ$X~+1nZqZ8>#V';~=;.OUJŊ;vʹ'dWk/|>e,qY1p0+Yly8&V/\rV:f[1Kˢn{XGnU,y"Q5}%OĞ9YSIdά?HUI #fN*)eΉ44c4%@ iYr8bf`1-1Ȃ*xbgvKneɒD[%Uk6MWL߮5)Vv}:'kvRQ]TJfF/F^Roi]2a}2CRnD.3#s˺E]ְQ/H%c͎ފjjiAqkq}-GO6gƊ̼խ[?@U $ԘtȔi1Ke "#MJYrVaRa j,$dI˛iuŝUo/LUٓΞԉJwK}8'ƾ1SNu>G>J֩HeKuWXRP*+&V>Gm'ewaY_\r/ƴ)VeH;hsٯʊDVG豖ˌSL*gT&MFƴi2f2B ׿fd D"Rbђ%l qo)%Ĕ s0)LRde-v-}Y?r\'LN}gѮKٲq_1?/'ẙJgɻ2q&:?Pq}UM+Բw-%.]뵮W*+&qnR#llUjGʐQjg;V[-e8e0cHSn$mFvzsҩN0YǿU9!!ce"QLdQMZ #dd&X" #mVjΒdORJ(+_fU&I,U&gͮP'z뎚ΗteLR'T~Q6kve$eSr0J'#KԪWIԚԡ[*"mg͵Hc#bfE⍊>d?u4Z)koT̀pXdML*(fӿ 3&"1%aHhUܦȖjTt{P0+Ђ\A÷4䢭-ŖJR'y"ޕ{g);Tz s9cs.iT&7Z 1Xwgɭ>Rh &G]rFEZvkT7+TϸRjITrݩAN.*WY_Y䗵tԘ#kKYnj̒?i=1C2D==b?=L*S F52 G"cȘ6儣# F)"%GTe}d6͗%̗m=f<-=632k?h)5癩y̴̜3=ئ&+11{R~1NIeq^qu}MqT*Kĝ]]IvN$+Q(t[%=yWySt'SYʔLu[ʐR^):’1MO^F_wƤ0bȆ1!2! „(fɫG@"Kk͏de_|4<̘w,ܓ6=3$sfgfi̛m9#5kTsOzvf=SLޮjn]#m193&n 1=uf]Y:]5VLת_85vb&כYI٩aMuS59T Z/;NOL~j~Rߦ2S2`6+3&rȘ_U%T(zDJfHbZcT.N%J@a6Ch8ܴYh/K@nP/Ȩׄ)zuY ܳG\9SvNId\t59H$2R1GܦbJ2sr?ǔ!$! SIFS[H ĔIHXDZEjgD$22f1JZ?qF lcQ?\KnF6SRbu,lQ7dct21,Q/ybK"ŘbgřY;xO5}g8=ٻw>2mV|It3%=stmj̤ƘVmʜ+$)lqt1B҄$I&3i{RIDR%cE99dYHQcDI^,Yj̗ G D[j116ydc𪁺2Q5&ٮemgهQ.ÉУkB>f(SGxi8#38DJZƤ׿' )jI!Qd 0,11wFn ߐ9r~U sYem]KZz|{[GZb.}$Xޱsˣ9$VQYT%3IO+\fYQɕL9\ə\YyL4F-t f5ԙ{-!5SBP@1 btKf]R YRŒdѓᘉ8?5PlҭnkivC.aɶ"1۴.ce);(kTsCu˘ێf_Ykfʏff<֕y%EkΛ=`TyOyy>ԑ8r3=NeJ=y(s9j6Gc撏!["?܌A#Eh)eƄ[gFRc=̬"cm mDZ4%*&R;ռKd Uli!X#1|oR8ԂaI6c1GR2u_ҌiVG-yM6Ъ jk+*,YVy?4Q35[ƐPKl9VeRSÓ3疖{<Α崙ǼfьlRG]u[c0pniRK2.R˴jE2I2TS@-2m-b5TӔ2 _&p/W3?,)撨e2"Y1E4^^)sX[[-{(Me>Rmiu=:D?5@~LYl3=_&M-,vVy_z1̂6%c 3R:|Sj2X%I)GX|^+D'q8WytN6÷zԗ q>rʐvn.sHh' i1SJUcUfe^ nb1Kli&){beXIMlR2GbFܲS#\+EhbJ.cY0\PxKb*nANn^kmByu9ƌ>ַڊig/u;Էay^vIއ5+/sf$yRV|F:J/;JmL/YY֯k$&z&RΨOעG)}x9pD&O|%KE-ՌYrh)%K>Htˢ՗VtWpZPUȨ &2u1Re[őkn.!eY6m}䲿`vټV[Z7h5#?2nF卽X=7_NF>Ivؑ%GH{'Tm=,fJFr1T/9JKj?$MWn5V%[2/۠F?KR^oKz(Q1Kb 6eFniC1|p/iUG-.Ɣ9RV`euz/5â9X1͑-#mzkݺe%_VG"UjX/LfL)0ZcSc>Di"9ߙ\5=~۾ҏS㐘[}(?c͑zZ~)xeZ1ő[<2ԱvS_{_lJʢ#-KuKP,9#Ѭׄf[\v=}&N/yͥb׫?&ؑqZ}%'Ɖ4$GJE.,Hqƺ=Q-Ɍz%%&՞#\ɼf^{i*F6NcH˭_y˼~!3IOUKzYofr?Vq(aFKBy^s i2ƫ&%KGZ+Fݲ5f&{e֬Αce.ZR~|[I5i{ f3f)Te2iE8/:O6qvVY%1cn3!8f./5N32zjKLe^׾_u27'i}aNmd? l[1L'Iŕg(3dH;Sɲ:rQ?v_ji5Pc˥-a)ƾLT-ǔD/6FYޗ B|Kam-8e~"J8 _::zIeKZz9Zf{8+Epb+cGmGŌ9NKyve^ȖZ=f)!.zcbX|:93%e F-(VrZ0m޼k.!X ˵6G/͒*PW}-us)^5qmǼreF~i^o/ͷm{˭XSj<%Zs̷ڪӺ 0YKb/댉a88ĔZ~-㊙grHn] Z.ȣZuƐ%Ô*akYgԗūab~}עnr%zͷ)RP>ԛXr4mEo2i<1eՆQQkeO a̯?e9AI ^9Uʼ!֘19fV*Fj.KG&5Re%C뀝I\=樏Xa/S1WmUܫyyLcFc ͱ.}W|])%T9[Z?ՓYbr*{Ia+4MU2m]DiyeIsoYp1DƌiM?VJRv3q 0e16DtS}d|/of H hM|*Z?H˰R/_֒[ 2d|GiZJ#[G-D3Q/.k̏lu2cF-nV?5zhʊfA)#Kz#|s{:83"zqL#|;. >UK]ԗjӱ3e~$[}Y55*}6LoΞȼriiIoC] Qdn8¼~ 0)䘇E*÷c GEnխJ [$1װ?YydܲI=*9u+ddzwr'[2i=zuk5^<՝I#_PUe9GlS-]?f 3`.HK _p[}5°siVG +-Y2VL̑]RY [bkvгi\{e M/*]Ȃ/ c;r)lYfCꑟ^I暇ca.۾;3Gt˱LŷX se)eKȨ6eCOVYIzI}|gךo?yuuX4a^"/Xj+*+DY\5c%ݣ¸Mʒn4K0 SɛD=o)>zMٟꚞ,V1\UaG"ebJH-W\=j߲V-׺ޱb$r_Ô ͯT%ëtO/vJRq+Br{: D%p*̗HGʨ0ΈoÝtזr_DŽ=l9,!暑HHTz 蒶ˣ˴DbTG2?zO[Ɂ!$/]RҲ5sTT(cdby;kf%~F_M#gG2?U?_NVd"5ߦkVFzٝ1Qkx²Gpak=N*R&dmZ*ĬarY_2ӭȪZ\'BcFd$0/K>[x.•JMАQakJ]iF\Sʘ2GȡX͕+G-yc.#_KF_Evkr3BiζHnfX]2^Z81+23&}x{$3cO̝~;zJzIeU_.ˌ2宙;}LwF*sZeXJS"Wleܚ;S1=~i/w21QML$\(fRrMq@ڙRQv_2eeebm292>襶ČJxy}d/柞:n_G3#'k~yXۊѫUDIVH :IS䓉*sz1%I;{Ԓ-a?GfIW2$elC*)3"5?[mX+ZY薘hMKG)`ԘhjH CŖ[~$f,9qK~ã/2/ S\f4 \6|Ym?ֵ7~myv1bdsLO!\$=&ƔjtfOf~Gnye5wo~Dpy㎔LLhsmnijV۪a̘ȣypd;я\ٔY2Zѥ_czXuUcvG|%+e _vזZY&-TK%5I$<[YcXV̢kΫmOnEHa>\LTkJls2XBLx8q|hڼj86%\CaELDRݙbF-UO)k$jWH,:**Ҕ<\ȕ0j汋h~c=,?׬cKRgD/U_Yۚw_DŽkRy7xIeMKɲb=qc=-"RKH͑M)ffhYj`B[̛X[|`=3I2mN올}ITXBK%mwm2/cmU:a iGZ)&2֗go,.}fqsԛ59hxdŨiu(Cd Y`ZJ+gU# f$%;&iꛪT65|qAL:PUNץ*5sZa5RZDKK8NHX%ꏴxUEY[ϫn9&zGVL4,{$谑HMõb^>zT },~x6|Ht,B\rrG}bƍ\^.gjP3GFKBjNdGН:=o'neI$Û&SI4ed@zhȑ Ag+0]r+6+>RzTIڹ1GƠ#GlVqr,gZ^yCkonfyRGRcZ11aً+[R.%s#))q6D3c/yM)ie5f8l y%lMFa EVm`Yzg,#4#팑əf3ŒA>中3nfʡɪ7K9ZuMNU1XCb3vzɴ,yDZ[џΙ,w2﨤5-^׼z&т*ʺQɉy"z.W- mbڹG}k*mYI:үK-,uwYzlMk؏Mґ}}gnk-'K0e6koٶl |̵}?a *3D#"kui{IK,h{NM5o־} 3f#1x˚G7kF~nduƉYad7H&G0FR$!՟>ddrO}^9A$\m3 ˬ̘>O|zF_{_?ʏyY72FLݙoCܦ׳|#c_ڱ3ְ_3Z" 5W[,瓽utmͤ㖑J=\()5/;t:/_;^'x\G镏хF9udL [-Gypu$#6䑓-aJXȵòf#?NC$\akgc+_ػ$af׼d Qc9 }^I 7^=:#ǽZ~^VV9D5C<|='o2&څ&f,^\]5Ú_˔10:lZ+Lq'9M2?i{uf~2Z~rJ%ezlϘǽ _yd_&f::#~4RY;= {x.+kr~<26i$oČ{c~g}uDW1s\&yG?{|$]{ͫˣWux'yI̎>g壛13w3WOc.W4Bz9هk>0 QZ|GIcedt/˗Jj.=|ykƹFΟy.ǬQc2`BbcČWyx~z~z?˟?{z'?ʵ+Q&;H&۾!#W?req~i|r+?:!9hMb G5˫G.1Tcc{y쑯K']Kz^^Gk+{䕏Y|ͤo5?_&Gctd׌yƓ:I*q X#`u+gq^G.9©ر {:Oo>{#c{%k_]}{r׼r+F0\ʯ|t+Bp_sd$^G<B+QRyf&˚_YozjF_*Gݵcx ]1걗#kY[ #׼2_ Ջd6K8kw'qZhj$fLM=2Dy2港TG9>^{ͯ}ܺ]_u9Ӯym_s_=|1cbv=_[s%e?*[^2_bhW_^3\,MW 3r8r|"SS;v '?&+ؕpq(w#te'}TD}j q(g1W$#ɡu㬙tI;] <L۴|w']¿"Lk>+|| 6*?o~osn;q?73zgW_Ǘcc*uq/q"&: T2Z8E@duX<ԉDfc_2::aM9Zk^ʽ鮩v}X)0Ro%]ϸSկ|?Hi[wz6HٶIK&1dj}ˣG_gm*LJoLya|#GWGJgHa_6KW>fak_U2j~#x+~L:j|%p\3<ҥi8)<ۓ3UA{`6%pD+' l$T&+6ͤ͏0c#i/#,y4b^'p5c5ּc9K#5|G(i$i#{__[V(Ϗ}5=\j.G?T9llSv.F"ի~cki>?sƉ\ky▏<&kWf F&*:bΦ"9sf2_QJYmrdjdI2Y.yٔIP$uښ̕9uska\3|OcE=.^~>2 'OHe+36|Ed#RD'zuЏs([Fv\CR{$ MqNr}W"lP7r#Y\32ˁUR|3>4;I97bёWodR*3۴gIFGVZ덹\8V&nOܞlgR4928s̡Zh\?u_CJpVhrH 1ae.Y=D-$1Cq\{ENY!WOT giI _ߵxըnjV^~qֽČ~eT+ǡQ _yRZ9l%?~Ls5ތ6znh,9oh7lۜ|q$_y1+!RD_]9wmuaÄh#e^aje=< SC+cFhzGc_F|5WaYOyggNJS=JCFb2eJo ðvc^J@ׄyh{&+}AL:%FsNf9d%Gf&?$797ӺI|r/\ayML8[[Wb[)c3cT |rURs>vo灔G蘑W;0J9ϱkj>Y^xx?~5#D3j+Y:0iZIfh;D5eVBexyR.(BŔMo|I:3i3#.lj$iWbIZs:Ix2<g|z6po[cK}!|ƩgtHSwL3L<Ñj*-GV#.f?R81']ȑ+t&7IZp8fr H|:Đcnz'#|ɮ Y19Γ>>ELs_͉;0ϘpC3sɧvL$ GKeWK~}T,akf V~rk‘#}ݏO O'ޞ%z2戞y_? [9 Ysͣ(ty2ڤ:5R;+1C|Vh5ʑ0?\sc׮SsnV+9AF^-w=P.Vb9zBQM2C!N|W-p9p>x"#9m^Jly3_?Ԕ!'>9o8g&2O3zsYHud(; _H엸1h'vk׌^Z3zuJsm8r=l|Gǩs̵_\+]c㮎F~)9$nr%$W9:Mjo+ȿ#aJ>R/ Fȑ|}FbIs,V5'SD?rg<pTΜ?f<\*_|㍹]gIru$^uDǾZ=Tbgdee$ZEP}Uʵr WtuF#%&\ ޼ _7I%nG${A7]<̤ IHs1!#xV^#2JD` 9vՐLr8"g&IƟ'4}2TG%p{:o9f֔#cǖ.;yd^_ jBaj7*K-OmI׬%cAI|(s|"c7{MA+$rvmMqa%Wv~eGj^ aWW^V9B"G_YG8pjuFRwos2{'Js}̚]KrU]U2ye(s|$"T*];Jk#>C+uh=s^of(YykG+̘@i%Jq0ÂG0R~GK:VԌڙ}M+SVcj4я!!W?$޸gk_Ÿ_? W_7oǭKu4i LD"ǖq_{e.E{e:u٫ȯ]JU懯^χ(cc^h%N13S7+C\{kHGc"XpdЏ,06uiR7F 7]N{:1\ ]FÑGTt[ٗa=B*q| Y>08?,!"я~{|y"{|~ޤ>.N<2Z+]0BƮc+[8VZ&p=fjnsy=kFKh|0ZET tYD2c/ٻ3U)#t'+v<{M$Z]ƬVSwNxɜ=Tsydʭhvu׌\-dw5** 3Ώ9zOd&:k?Vޞ=Zlw7y=6wUvs_?'>J1>ɓHs8G>y*GcS*vGV":裯SFILH9|ڛ3' ^}GF'SNVi^Oc8>o|嚘+5Gd6D24ItV["\9|~p'fjG_w 0o*jd5ڑkVTӑڠAt9JzJ sۧ6T>zeWG6~ۧbvaIՍ ZR2;'$7?a2?ov1Z`᥯,->䲔␅0Rg7>+E7@Ԣ/59vdsy.,yᑕ)\Mh;⑃¶~ X9.#"p{~–Ņp\ M^zdbi1P¼EFhD&(m~ tQRbqhۢŇYxDGZ>c|=>@i»x)tmFdxts] F%ok%Lʊ/S:_`PxzЗ쵖#SFGV(quH9+a/%ae [Z @AR@PPCD@U0ǮGPPK KEp1Vr`/Y)FS*G[V~73yʥ^^o{{`Eo >^|}q;T-$z9yr< ,H,T^`iK_]7g4u/Uo)w[nhiمe_Ja/ %¥7T*P(/ .U< JPĚ\| @Cy$K!b)K>x۫+J|+4/S7cwe!*^$O;h_W ʄhbZAy`}p +];np~SX;|^DH立"{+PiA 8yH؋dZN`p zB1BJd KSV[UmRj %0Xjp_B, Xü_ݧ}p' C0·/]_>9(K^z>OpWn3# )K/q4?4nN)toZ)ox/,Ke/W(~clqZ0tp@@, [P%[R(\(RK(@-RR{i!K_z A#mٟ ?uل` _ap? 4=s{lQJ)akw=KL}ɇ\9Kg[ wCن++/vۗ.N -Zh~a4zwm]" W( /[F| PTdKJ# 0 ,tm". :)W(0TR7_\ ,  mU\\h:-~/ s9f۵JȋnSo븹rLvlX^|s(/DQwE|&&mVOOcx~Q`k1;}Rt}mƢ*zH%&/[=Cѥ?laHl@P^(9R$.R* n#.K/`8!va/E mk.2/;U{1^na[,,(Al fVX] ] XAl [ [B^#D %ZtMphނ'c^<[\4<ۙO ʾ2c_f,t$j!'^2cV_ [KKP#?p`Rc1?f[rX n V(v6@Mr)pچdiF(K2 O#MJ$c}$tj%\ЄV-[7]. JJ0KCemb?OT~/XnLө-K}:O{P |eH1`Iؐ6<x]`'`YU}-pꋏ9rq pؗ.(lb2x$LDzE#%iVa^ @*Bh2iR0]ЂV vBVԥł^,PZC>[`-iz 5^i)Ofآg[ GzWl[n;LozkC\V灅] s.:IѽlWeXm"`5x^,B!!Ea/jԺ#A6ejpFn]Z* ]( \SXk¢2Usrp/!4Y-ťK ʒ5TY )+|j8#ꗾ%c>eqg~<oS0_9_4u@rozyGfBP }/wuKסåS\GÉ/# ,;p$X*/ ʁjNӹvKಚb[ح  *TZD,U"Pi*ˊE`,a EH 2pK \@€`eB;'ߒo(q20kKC_uAp_+ſ$sogC%pBo/|I?^a!1:y)D y=?Ms4̈́|q0Pv_\__lpa^.7 -, y?*<y/$ϯ~ LpK.||p, Y\_ܗʕ\T8xzඌؾeݲ)T m'*B])PŅpJK8X*K JJR/|~/Ae`2,]ot=+ԍ$e72ls]^N`7x_‰EO/f,7|,ـ4Ssa eaa/#~3L`8 |r/+[!ceeK+paJp+[ V-2-Q`iahA*^(rE.>Epf*KR@0#ʗh2G¯{҉I-=H{a|>ᘯ|Ij߸|[:/Z\E~0]`)@Fn gSyz|>d[lA|Lp Gv?a%[:vX|!ed² --HVRA"-ڒ)D2"Dv KP#"px.a~ R1z2 u61ƭjKCK?W-z;OJo#oYV/_v8{{ǯȏKOA^Ot8'g͛AGp!c-B ]E.!++`6eVXc@3 -)B K. =""Ł/~8?X] 9,~7Y|hS]|9v^ԟv ,{. m_< z/6%.%Ee?Haݤ~O"~؇7> مf]mRЙ GH 'm~ `ȇKy$ J 4۽(F(K@P*T*B te0py hv_uO.վb:%Wa<4_uۿvaN  @.쑶]昗}3_cW[9B~ /~۲X6*7EPU3TS0\RKʎ^@ -E%%@ C!]zp`H ( a҂ ` dpd E 8e)_Vu$eHe+'Ġ"<25!DJ"^]ւu;쑡!)4OԻ̝zdO-~;癊.!Wcgf?[j=YS5_fdd8˴YY%]ϔLO531cZqZ)sfR\VyJr$$tJI $-DbJFƤ$,e"[3Pc"{ %8#qKzY%7Q#))kt:MUΨWJS2ֱCi:VRYJ\浊`$8eĚkFj\]&=Vڳ{juyzf'ٙD3;i#S3M(^1CqtLw32zL1CCLeL[1L"*+!ȂDS&JdRcd8R 2ܲtTKI0%[W ͖1j11^vE/k;>xuNy]cikP\돿+UuLғm YVTr%*jy*Wywr&ewVcdef39=3OR3GəS|_QKsZK2K꒒a 4bpBA@$ufDJCR`FHt@-YB04,uL';3r̝*שּׂ-7G2G_ү*a.m\c}IP|ooHK̥;qny4*;+W̌UǺR;?hMyG*:Iu<|C9Ç:ǜW.3s&35c\L0en30Gr~\c^"dK䇛1hu-2̘pHj̠"ZB$j$Rb̺$%ɢ'18?5PlҭnkivC.aɶ"1۴.ce);(kTsCu˘ێf_Ykf+*,YVy?4Q35[ƐPKl9VeRSÓ3疖{<Α崙ǼfьlR7G]u[c0pniRK2.R˴jE2IIR%5UjPL\TKT2/\rT9DڟC̱$Gbn_R8ԂaI6c1GR2u_ҌiVG-yM6Ъ jk={uʉ~(k1"fz*{9M$[noY<yHy9g;c>LEֿ%r9%1c=2c}M is1D _ftH'c*ՙ)Ƣje‘PfḆj[DnEJ{fW%e\,_r[]ߙ54+uq&k"q9֖%VKlkYTqe)GX|^+D'q8WytN6÷zԗ q>rʐvn.sHh' i1SJUcUfe^ nb1Kli&){beXIMl2RKa w&"*Y%Ћ>l9%R6KZzev`N~9ؿ̸K3|921.]Ϋ.s MɘŒե>0VkJg2=BIe]i|͛)%+EǺkzz3jz.cJSTR|9$ VaG=v!EIENDB`aqualung-0.9beta11/skin/ocean/bg.png0000644000175000001440000016423610612341735014257 00000000000000PNG  IHDR":9 pHYs  tIME.!etEXtCommentCreated with The GIMPd%nIDATx]%͖cNXk[&R7 %3%j L9_f"3-$hTI4<%<uR/ӵ~q$&KSD'At+`UyPq`nS/^?R㿑">˭{}F4=\*N \Q XhImѕG]~u7ݿ*wŮFKVXiz᝔jn$`D]ѺOD^h_ܥuIL2o&:j^ACY!P<^op /=cM3O)J1]%_O@넮usR"Rq$6󜎩x(Ju1ڛЂYd"; V:zzqzߌUMu)hLi{*pW6IBI x*.KUNSWPی ?yx`c))wC&3'/ӏR=IsNٽ, j=XMoJ:q6q +ap\89`"R1xhǛO%?CSF5GJKc)EÐ@(boG# ?2'yTH1PIԆvb%|V|c^Ȟ/+ nK}!M v7횻OՔP4EiLTG*GAVޥ9v͝v~&,dHb:A_pMs/*E`:nU+ɹi;lTvpX%ݢ<մ5Sҋu m޸!!nZw2.;*Q'~s > AoiO?k&׊`{Jɒ吢*ipr'і)C8Р΃9wdS _5Ohool[̓|.dhX]\;}lh{D^^_\/^Z~B MVZ'[M}"XdӶ}-4CS9޴GnGir8v>粓 jg-ZfQnwK[WZRv*mܓԭH}$DRsYG] lëIKm3p֨_}+1ImT(dv+#j>oDWe[ѩ, _dҜnhfakn)itd5 ēag_m5vH873+&KM:?"Jaz:J&VWq9/ix~RfmH2E}?iS7`Cꊙ] lh]YC B787%]PN;'6単ri]f>WduRrɫfwܧZ9!T!%IbMWnW5PRC8RJaԆ@=xYɎ'c(Mk^Vne.R܌RyuK۷=JYI__ ΖK΂X7a<eu I]v=OJ^]jjĶjetP="?4_BM[ /4:q\E&1O<|k!fTupmi:yhv: ƫA/huMKW*n}yFu?_h-ӣSΡMv#5Sӌd[xl"ה*Iݵ;Q@y1Jsi}xߺOMD -E-CQg`E5Ƌ7b_%x+]vOSzE*7Yb.[(eO_C_FjspA|z_D7Q:B]N 0yiRBQDgtX9Kw]:Y;jvS\m/VƣC yk~a_ĿXbmKeOnO 42b8UMĴ^߬mp̦H9NzO$pur=FhyD>^T0k35Y7ze/bSbS('z9MULwb<$vMofxǓ "*O̻n7 7<D+I]SP tAXY7 Œ ޕA\\V4&$?e?X+T@o2umhV$5n `N|{0<~V9leO8L-C~ICM3⯴ʿO㎫%./MF(Vh~S$XlnX41; ({ hfxJT~!i:kuߋ޼kIjuai bZANK`47f8bM~n*S%uIMLMBK#h$Z풦Tu-wi&'%ܵmhQp}h'Yx)%YVTt$X?Uu84)r0kT?b- /k _AsyJrD\+撯wǨ[ hnoVy>/?n?ʗ>b.uʧ &Ji3o錄ȝK呄yu$͠gZ+\Im_5NM}䨃j֣Rl?ܖ.e nr6fHꋶQr ?A%fO5^3MDvJ CW[2ID6Z*F%['kè's>?=򃵫^SeTeMX7kzH "BF##nM[৸{EUi;42rheǙ+Ȧ-?5~SQ0NٚCĞO'5_hw?4F/!"6|sF.կWTۖzhɃlS딛VNAbzCڡ螻Ku*򁦺Qm٤  P. *' PW.F4EվҐ F?*49J [fN6Ѝr*+@K~&F+k*{+Gr6q#" NBR8hV=*=1u7QZħܸ&C??k)b1{-:t_OA Le7T\C#THȠ&Yʈ+j~3Ss+B`kjɻ[Ps[ J_0ҩ(OU_Vw[yv;j(PEZ2ǡ1gлNJiW9n9/(Rt+v/FKINY(KG xLb-|E ~ey#!F#^^EݴE z M'Q^X1o:R.MK;wyY5nQ[E'QkG{qb_^gi3֨U,QW Ekk .XSbJ PJԁ.֪C/,Suz6=Y#k5%kW9hM񡲶Զ9 "P_Sob#R&!'V|LVR [`9.u昄7jw]jSqb}+`$mv(ntJSQķa~Prӳ>=˶.ײ!ZWͫ*.*;8Փi_jtւ,O{8KFY[j6'^ofA^v.Q3GͧEeu9wdz>?rPs {erQ v.}'rȁ7jU?kYuTc=6*<*;ٚ}kMR98+UѿKê53p+RʧbƜP;t<3VFL %_[ϛED%Gj2aXWGuF S+c ˺ MRqvoҼV>XïWQ%[,\r7sS 4l'w և[S%cw]^C}c,n)SqҞS=a;;uB(Mtpvdz:$fD Wj:vW-Mor(:Qg(䶘E\ѥjE(tGO<756$:ٴ`AQҲ-[N!7ĒJF GvبXej΁NvvGm8aϦ׭-5 .B8_~/rDy>{O|ixY:VDPMqRtaḭ QT35m;.ieWd54IYS{gmX o?i87<`v ؊2 j'-ȍN92"YKW@D}O Ԋ 2-)ŧQV\D3GLEZ RYV(b=7msXĎ'w :t> ' ״ ng+T :79wGP%ݪ$lgpqty8?[v_/}2?wđ[ǖ뢖Hf݈[1MJƠWxW:BҮH6HAuC3 aQfsy]M~vs'XPzu /*C)GJæir)ix/RuAG@+S!_Pb2-h:5*X&'=JqXR+VY& *)7حEN|bYr)C=p@FL3 N7  FZ!u{}gS}hMqaW_/ZXQ-EM4ZP>jRCr̔t޽MC늽Sj_k4l6 MĦ5DfYTo17ѓ$9i)s+5xt]/to*_hH8} tqi405 vXx;lb{M_DR7ى&[Pޮ8C4+nNL.7fsO֒بXʥ<ڞMÏ]䝞O 1=7KhCHd1IYYg4nhK2QŚpP@,N7~W.IFT&-2v+^jAܪ*tۣOF.RDъ`$Z]:=vu %=g֗ZSGk)PNeEиI\Z '4tcBIb2ТNn{%iB.τ]<餤-9vfǦ9? 5Ao>F޴XqEipkPa:Y5?Yϛu;篨=H#ƒ.=/ jip(pkC="K!e=q1hf};KKS IBmd~29\3"ZlO{oP. 4#e3):X؂SJj&lQDjT},Fj &m+r<Ĥ6ʥ]q)\%IZlƁB,[)y 3*8ahKĥ,>85`*I,Q_hl8oz7\а_»mDӚ覆. [a BJr" :љ"|HQ ڃ*kFlKiTXdmO "vjS'K%R]Q*9맽N]C[WM/CY!bexkc ̎@tI =櫋6b*J e)IkB?Ȇni*7HИTݥ$JVô|H\0"%нÐV> rtNWE%EJ ?c̒K«S}2x'i}.QLh2aq= ,fn,gqI[YGVZiL XDiW`f?pJdD? _Q&>FVod y%~u/Rޛ[M7 amn}@k}V\V?IL-~RuK6u-TIAS;Z9P dR8@>T!TWy#5Y=}i,k󺉎nb#$tI/>1#.]^p0/qmN$O7QvЃ;վ(iZ$>eu{x)"T_-V>CщhU*r}J%-1ÛAK~:TJY-R)5z#þwZiN*W|h/šZqH4Cq wNy*?^nfUhǐÍ@I.CC`:$bf ]kᐚyHTút3P4qiNFDx&1C ]Rm.ZR\j4P[b!O\n NjӸOߊlAHT ~ 鱔P-B.=7632%Y!DjfyaىȇPlψ2CBDci mOeEH4PA*~ޢp(Hb#QlS/#bdָQ?jKH& XRZ,%:ҶwoM}8j'$OF *޻(jĆbG /Eha!7b E?Pb)1Ч?4zmHLhO"]G䯨ͿL;+v~2U_ C{D-ύ}8?`nX7>Q3 *SDEԆz 6cw=;A@[EhEXg!CW;X>>srS"o>QlcUn za]I2)HTi4z8붾+ dLK(`aBETf0L1ȡXlSz(^?bu¾߱T۱Ibbݮ|w"YH 4B]4ȤPn>6*a-"Ggc 硼5fmx6aFm`n0-}v3ߓqQoG~9 ,;xHVRDe !ݺq-nI[ j>XS@)}-R[uJN޹oM)M<`.=⋱NE^ -b'hu1g$>PEi]N;Fy;8hI;P̦FA`:]MRM$z2  "=Omkw {tq-h@BiyZiʂo\h);NFP.Hu&DK^#U.UVRfU!#Ck]qY^Zsfx:CZWe^3ƝPQ-G陼I_596(mJ-uOTRUn4A`5M;ҊZ8">#~uŶrLoAݬ/'h5V?IRv!pU9i]2ju9 iPWtI1傉6rIP)-u) {~vǧTCj"B5K>$k{h֕;E[r;U`IKmgI>DgH\~?ǰ>:]lH\uT^`t~Uo;b uSa{9E圬(Y!^=nI&vضE6bIfv)nTֆUPF -|҃|0 t'bcKV ֒M(kRRoO BEOd'*zZhYS\ J8-2Ue]Sz0%=RHi|ӓ%Ifn3fd߸@wƑR&5_UYevM;PVxa96FxWQq94b0PI,;$.e#W"K7mɚ`QE).|)opZ@yO/zu*bxvJhEۘ›UZ hV%/rya;l,ʠPDO)&KV]0I +[R5eYsM]10!Ů(KqHe+0eE 8c"ysP+}˳V -k~j$=X^#c158}9\AZ)S03E\Ӕ"N5iL S!6v )D2H:dNDcxS#jDZ,&~5"Cr꬇+>##V\'W+II-b(K֞mz^掐{:^;5Ehaץʩ7f%%(|)nt1ut +RDZyRu.=y+ozJ Q.f_r˿WD{CMe=|XyWZO{Q5G"R>4?Q҂Fb,dP5tSM!V'mEe^Zr""p'(5XMuGL
    _f.+;~RC^|hl/T+tKoF38E]<\xS S%%=ԓBٱL#[[FKݿJ1iyWoRL_o)t/7ƾQ?tsrtC=-QӪo7o~PpޘRװp» T>zJ(Y]m'kɲ)͊tUx.JI$&>vWvƗHlfd@H)kD]TwLגriZ7cm7TWS)YEݿYՒ„iU+p: `|.h~lP*(4*SYMrf <A4eRksb.@yA5ʌUZCܩ}ZcgZ5+|r|Ҽ-Gw uND XOGD~zT.MqᱹMnO:}_L1v5=Y]>/uIeLlDznA"{P +bC%&-^4Y-ݪ\v)Z/ݓƖ\ =݆KO/TË9gu3-MžЋzPȍ,[kmMYhS0CbcmR5 /p7b<of/ jf/iQrKj^o)?ut%N ~z-ߟߤ_խ{6qSa?꫼MS~Sܓܒqq|Z1^E(5bhk~6l{,qZ9(o$߄OžkqiLLi5<q-\ +\miKK'l՛jyގ3#VhMṠzEQxHf~='[rVhתO柙_jVfp] k.r7MY/IXRx'7l`u̓<wUS~2<Ȃֈ%l1C\E,% ^"37K\fAY.K0ozk[ƚDů!N{shP;a.ӂu[o_ ~W>i0:hP; 5jIP^5 % &Xe4$Kڙ.m D -͊r>d_˄zH ,{rlr^ĐqLThND/ h.$֭#TeN8"%3C!ru>mA}z :RDx,mڻ1a*6%}-[.eu5O1M08<^nZi%K^PC!~bWO'YCJƭ\,BMڕCH-TxʧDddޡ<Х~3&cgY.vRhybo,<&Fy1 7,n".zݰ5Po9x[_XTCۡ~V$wI͎z'Q5R69I)ҙBш)/*ȥH7ZnV(HbZmsu3EboBI_n 2<}8_֊Ff9~pNk'"/UeX̏K+-}x`@qlDbp[qQ+pEI^ƌ'X"8'~޽Z&W>>c[5P 4ɽ\ZfA4;V>oz[WD ʚ[? Mޥuv\t&:ᆝ8hiFj %~&&gIƛVX+M"ʽoIJ⢆5CM51ҺpOd /3oӾY t\IʛK0d_ 8)Ef þ4oWA6$`%~ dGv=SDJ&Hj+6eIU Ф:mGrTnnNl/d4&KdkrFCUہQ;{ix>ny>zyd:OǓ޶|+WnVGhKUD*٩r &,ΥY,РuSgi41 0d1A]!J5jM-Rh/ F*rw jyFl{j&Ͷ[Ak<;0nA*)5͎Ԛf6Iu]p* =m*iEGAaӞSe:7.eTH "rC7gܤD ᮰$J o;%߬7mvin/)"r'/Ŵ&I-P+)B@O1jS |/т(.CdMŒ*|2/>T_,bhAKE 6!N)d0v <Lmml;j<`O|PL/fg] Y־tBUMhjiRlPG#vb e hZn]Z|T6G<'8jejSE.R 5b5zR:;C7W||c;ȟvk1v?@_˨М8%h(It,h€%5:QGne6.RM؉¡j%(@OURi]) )}Ԟ:CiAZƲrl^Y u/-%L>)֤%CؠNJ#6kTPcEGpn0#RW@KMpOn^_~"^h/bF.|%ꩴ(a57!9dX _;gH]ջkPeHisknhIDRݪ21LnD`@˳2E wr/j .a"=@MlDJ\j0 di{(m#DσTJӴ3<:ѕ#Z&vh 4+P5! N}_܈I>Teuw.V\iB< D Ejuӈy+aC@mzpTTK[S%yg|5u Ѻ*_pS|o|ޮh:˞V{Žꕾ&-ʿJ{2 vk;rZ7Ք."&nR7(֥>3oOt*+,?M4f|(JFYZ^"5$2GBK6eޒ_,dmAĎC+Lyoj|E=(kASZΒH"L=h2֬jDpZ*YrS)KBw:-rkWj5ė\jBeS ܤAk2l*pe-hn=ݭ<[6^[J5Ogo8k.*9Nv+jFkR:􇐨P. k]\Q2hJŢ>=yzMd h̠!-w0 ǨPw-i$bKѡ8B*#Vh(2Nk\[=mYz{[}1k5ppUa*eY n@⟎g+#)gZ+"^'s+%^ͯI[>T3%cU"'4MѕaWtviyh jDDK'3Dyic- u)@è8Y;OIk.D*EvsEQ_9!ת]5Zj6XŤUЙ_-) "RVL;iS+w9iO]2ӺŠ@~AOŹ#@F&6.yU(U|PW2Qcu!Ƽ T;sI-[q ,/LSu4i/Y/F5biV{y85 #{gry*BY+Rj4jaS? `@ wOKeLy:JĄ0L\q@E)SQQZsEx+irİCWQ啔*,zX(bg 8#WQ(NO9OfhR7S9UpIUXf'}JmҬ2Y 9puf>JsVKtZN,_aiĚ[OݫkB-*M!$ y#v` ֤kgA \PRck'&+UmM:]_fV0,KWl˹YL+_X̝0sB#.!D YJj ` lFuE%Gᛵ)hƔI':Fu7 JRۃQ<Ym qRQ^uz=:p55Ud0uV;r=h^D[e])1і_PD0f#d(jpc}rTT L3b}ss97͠.aωj/Ӗc0.(EۮOExNz (N'> K~:Qᗮ` 0*ILt^?MbME,F!%^D(zU 'Jݫ-yiڀRIYr;kJ(B("546)Ce҃&b#}LnT2fm 5YVJvuF˭Dq:2("mp]RQz5(S׋GpIR6GͧsyS.d잡*MRyBcѡvTT)nE35bĮ5hASp;3.t%D e5(!V0QҦ-Д"j+}N)ņ&evtxKs6I.$J+0Ʈ v,ťˊ&/lk]Vݪ) % ^UrH 60v|vLɫ0L(QNV0vyԔ䅛uEЕWy H7|PZdM`TzW]GzRs$^ђ;"wꇪ+;\BA(VلȻ2n.9~Cd (MRáxB7pW-(ި (h0T$^h1aTar ^Z0)ŁS&n:'NX( ȁ;[ iMepu壴LS. "o^ưq  L/괒FxH3lZlyW2R*]!ieSw$,/mk+IE3ʓ0`A<*0KԚցd5Jmsu.ɲS*ՅJ_ڱK9nS OVW~fi&at_ iLR-]/r%3*G/t#usj5vhk'  [OY3ev橾k^`)%4\e *6> l (n&3j)>5&§,N }OM^rGo.T`0-uafxS$}jEfh yrbLyFqW"'ڢoTR/Uw $Z{\/SEBHfJ)䐔V P&XicSo$$XDUbXFf\EH:=-EagD2g(Lnj9:?u\^7hxs4\h;Niפu̮۠.΍"МLBopt!#ZA%nU{[* <$GZjVC)CR1hKJ]q#7-(R"r6wU )zj!:XyRړ:OESUtb&6L o/TH@@:pҖCT&Mt*h -I< A<$;4ә"+Q+)"pCnJe7KlV|:vD֏XNctuEpFmk]/_/4>w ԍRd15Tk5ꔗ,qܴ-'C{Yu7[p#JC\M&+$71Lm&RF8bfTC{4X̑ibP-*$#XwBBϢ`kKHʎd)7oÿBv'jvHBLՎSrC8;NZB RycF|I֪m;]Kȝ"ִ.+.&7Z MJ]Zv%FĻzh?U/{ݖ$? E1\sd-啤ȮDu*o2wX/{k?BA,!5Jz'aktYP 띴<$_d~uEA'u Ok˹WGrjRدrS*N]O'"촆fqj^8K#8Yz&Zꡥu1LHJ~y6TubT !qDrФYǿ%SbA5LL3'[`,I0PLǗ("tDr4ї y%h!]L#g\+$)ii?Xhe(EhS$vMÕYc-y,1 I,l:K[ĺQk}2/>YIUmT}w%C,ޫfk:6# ^ˉ]׬(&Yv.^&`R \#k%d)FEѺUW-l(\DiOY2BZD _qb&h"C"StPR~Fĉ7tt$CuUv ޵ӱ˃|KZ} ?1Y0%74hJ#&/%zGg}'F3^ _P].+(CdɁ2Њ)uHb B[imI;Qr`{څ\~S\ZeBsy!#iڤKJĆ"C,Q1%sB SK᢫>Ieph|Q{( XXKNZP%.MnHۢ;wچNbR;h{idxS9ԀbS,F K}SkAp8.|:(S=^T[))Y^΃Mr`P+5QCԈq@(-DR) Y V&.Ų-h;P9ƝQe8%0 aBZ2tUrH,-'& U%L.d V) G҂"#e b- NfWZKӬR&.6.ds*WmRݪLGrۘeo#k:ӳ7b9׈/W׮EҖjS-DX7a4Mדk1kH+Gm)B O|4 .XX҅&bnbV(BE-a+ ?#J mAmFs\.BZVO/LJdD"MYQViEC'HTba - Rؐ-6!%!EvjS*Wa"fE)GOo3Idӈ6ܨjz _Vn'טg-⼬oڟX_D!bк_L-)KEچtk@}u)mI[mؓƶgtw&1i튽)`g|ѯ8u\\}StER%_p7w8yF?c4ES)v$#xjIXNM $q5/]1=UI-1969AOT""p(l^rO!VMXLlF%n4H^25BI05D1Eز I^NJB&TK'UFs&/DѤd,i%uNEOc6`GMj۔bѪ})YMl|~1Ֆcmp -i2@ѤlIuȋ#&\M7zqI=30I5&%yS-#tui{eS}3pA/sD:nwfO-R6M#1%f8Yg(/.1/@!UͰrxb-X?X-@v9B`{B-qS&vj Aٝܨ aX=iEL!F6jNQ-‹SC9jCC\a ղ5n{d_o]"اy䷷+~D8bk:\3AcElUH3JWH~ЭKm7͈mCר|!ź:ckyZi+Q: U!Bvm5,E'?ge92mmr RNB`"`*S~Z@7%i xD5tb9 tw e;"߉ޕij%0v;$@-ը [x%"Eu͒JkiM:ܪ&lr:dXa׿z{_щ*ʟD4 +.{OX]WڦvIg?u;t kȡyr2+rS(6ꢸG+؉֎-UhSE9յ=zi"lbI* uRk*pe#'Bu9.K\@IQHU$ Ldɥ(ELA,U9KcgijHJ(l |Aš=3՟eBul^l&&Wԃ6թeNSeoąm'^p=`2^~JZ4|MUu,0J߰oԠ9zt .qz4j&QѨ{1~q>zވx=UghTM[^ui~6^["͠RGf3ؕsŹȌSۧV[5QJ<ɾib\]MeE*J1 SP1ـ?ß)adR&bP8P%d)'HU KWp bu(^`kg:IYĵ5\bwt-UgT~Z*3jyN:ujK1Z>Ds|Zzl:.Ѓ.t߄p~ۃME.YꚱZ¦eMۓ`tuEH{+qMj" :9GU1ekUmpHhg^O"C K"tʪv%gj-R"X r1G%"D($D-2X )RI175]ijɗۆR=!Vj cP؁GW2da:Uy/yQDv)C.`yiwAEx!a5Z޺pwƛ(y*.枞spS{Q}yGW_}}:a%K * j~5Q#uOG+ڛhdS8oYOt|QJi,q< ?ѷdrVjA=9/qMdYuRuI@* Bh<Պ)]JR#(! p --Rs(6EJb1 aJJh/tKc+ ,b6\IL㥱yqjn7o[ěHmTIQ[;3w'{079zװ!^@pj r\^wbQw?RBUB;$nF i anEa"phzR;|tB'f536wkZ\"nS;μKa?kpYY'Zi/^WeIXu$FUYeaKSЈ E֢9 lRHl$x `ܰEV&B J,4w*Ѱ6KuHX/jc Y)g=lSGIVEQJ_>}I-R'@yWqЧ($]MAES+ݪXV07.|ΦȈ[umhEL̈́mjM*ZHbrk/.֘nSUK6~-gT$*okɋM!w%_t47ZZuiNvk5Jpvt.x _V2(Ճ-Xf{l|j7_GɶXXqPU:SLN7׀dK)z9^Aqy=^Z,|ʹ*RuZTbl\7'ۻ,,Ɂ#pvY iO2j̀鲢e`XV BLz)LMipWܕd]ċC# -N @`C"(|G_7j0ٍݚB4K\/*wP.~%m7ÓXqRnғmR$ "0Mm2뼸.i_ox2՞&U\OsbH'q,kW\>3B]ͬZjz7R|Rzr^5r/4ܩtwyٙK[Q@vGuFvT,b h5E32K֒XLZW.>J@Z/+p*M}sSr/Ąwڒݝzh*'~9uwm?'nдa"=:/Cqvwzv}bMI~kb;dO_K`ùI[ ۸5;mPyǻfHy~A/U[YOFi4{@97F4ԜR[hS;I@n6ewqx=OۊgI(w]T*U*T;k) e# ɱIX~*U;Ҧb5唷đdw"Hny|◗T ښU#eѡ$v4Ͷh*Vmg/Sk d߈X`f/5ZhM0x=],:,NTH7U++!ltFzh/N=DOY/1r{H&8LXƇ:B _G/`kd`~Tʹ/7kcdMAe֔>]Eݩ\a5a^ԚzNy7Ug:Kd5s7Kڈ8,%CWd)WIF_κBr-b(ߔb)~w;L@$nMi6)\N]v hNmin.[yWS_R ;''qmRﴝf(wC̟_(i g'/Yl_TjNmx=]5#$`Q'(ճb[t+$4CCm:F{j";JO_'^nZ+MJ}VgCS,9_oa[4ZHSuUh0CJ0dCC䉖*rnM:|8a>Y.yةN\lI쏨B)EU % x*("t\N- wRÿ>:yH*r>]/*2^O|v%U:#*TQfxuiqR<̅vUI]jfzm^zQ_|h:T/)Qăp_Y7Y2S3."&s#nnM&~Oz*4bn?QGը4w˺T7|#&;+~w{I)mwMwec4+t?aw)uA\4}6Z7͈lg 6"r7i"z%V[4isn=om2NѨoʔhMZ}^_ 3oPqiQRl=#lK(pk\==_+~QcؓHVZ_Zo,):YJ,7"5r@9y0lK+8ۃm"ooxFL!*O] uCU{7영/=k5w'6)%{hbWEӘ*J/s$6n>YxZ<4wA`MأYnƐrmx~A6͉XTڋI`:.U+ɹi{9Tn" #r*~x6tդ5.%fߨM EneX~8]3;EOEH7|Q9]]аݲSzJj5;ξ45vH'xm",E7ibW% C{j9bC-PEm~',д^Дw*mi}u w*E6mM\|B3ޔ3Iv&c>e'Z#&-kؗ6D=Rv*ED'ѩKDUz$ݔ/z١uB7Yb`T,turX%,E0(Sm(Nf%;,7nBSxEm7& ;—/1{hɕV_,Sy2W%gAKד0rY]v*PȿRX;J&VWqI-:>xB __'eֆ$C/;-sp 0$IOjΘ)_0FX7T'+h$c>aHrsYyKytOxO\z).ڛ]ߝ=4LNmkUީh4CBM[ /4:q\I&17<|k!f0S䡣E4_"7 ݇J"#:$InnLGZh SN^Gt\hh|itQj2Ynrʯ_ï=-A.˷]ׇn;_~%B%{Ϣ߬{iLVzƭF_u[Ns?0_]\7Gj_KU*oVpOJW3[yW rv4u{0#ֿ(%(/Cs֓ovca=PRdQo:eF'M#d^LeҋL3;1ei "O\zlU{j }]xG^P )%+P줘 <OӔ":r` "<qߥkGbӾo >XEZ7e'/ȗkj/UީLkcXگćzpkMxȈz7/ɇ-ӣSΡEj/M3Fc4YU.~' (O7Fi.Bj/BZԢEZkyVTc|6ZOek®i]7hT9keO1YV{9K O0xÓ+ፖ,ɖ}ko3w"pYUК `S]R4ӿ)嶡ZԸi3\9i?|)?XV=t?3U0b1?ygĿЊ1뇵 7IC;⡽N.G-gՋ X`V`s&7C"6-1zR_Է$1n2ob߈o&*PHm$f6zw< "y:k\ϙEeʸ.Z(4g"ɩu.iJ%['{kҪ|R]ۆui ׇfxR[/"#)^9lsSkm|]K= țU'R_1|ž?GBDs{~mx>:zn^.X₿嚿UQ_-?knm>Avvâ94PQ@>8Mܴkpm񧪎wtj֗Щ^^P7]-M@U KE\0 rz]KĠti7 k2Е:qM(JQII=0\Ob{O`*T?`|/34v͚^-*R;ꆈP=Q/tɌEEZ-NŤnՒn^S\"r|U~ڎf$vqj%f|y#R؞Q'qP|_QJA4]~YTW]Z/$̫Co%iuhAu{C uRƩiup\zT*퇐ruBҥlM. @W}6*B]u'H,s fkƏKݿoJhzp ڋڢjҐ F?+49J [fN6Ѝr*+@K~&F+k*G#h8yT]!uVGItq+ˏcX:v-Sn\M!~'~PKߊlSgMQbz]_%1*v]>wZpz:JUԧ;'+t%RPw6ox5FU<׋{ӊeEl=RQ+͉۫cb~mȚ$Q)7EQY]ܮf}3֭mL9oꛗK 酁N[3ԛRBo1/j$~q1}ߞryL4oUt9kL]h]qaQuD{D}Q`.(C9Xcg쏦 oV*aldz}f-hY=Y-cvGuTg 22f@*Ok'Ɠ4fhݜ&#$YN↓ک?F47{-ώvB9bdhX'a.n[4VUjPP].kZD%_HGL0^D-9K_r6Q N[W/ %Bk|wc'|JHĉ)q3eۓ-Q`Ph-5?%KDS}&ztL]eIndW驕tLkgHL=+X[MzQzreVR};ah]E5WqQQ枾^%푌VŒsx-UL(,֥CB-TS!q9UkJa*!/OP؎Z`F3V*̾j)mzCщR]>C!,.U("EΠ;>~*᮱!Mɦ5 mIr 5%Tp5j8ʵF .Vc,tt;zoSևi߸{6n5h1/Ow :^Թ@\ƚ !ߞ Ӟf]{-PA_KZ` S^E o/bS}Ç$b~© CK&nFn䦸U -ьoő9SVTʩ`Mۜ;,N)(@vϋ##h| ԊIq}3NwLQ͌,JRܞp8,p+,MK l"s' zI]y9FCo!o8So#kC}˛bu u#-v>3>e|/r~u͸0]ba&n[Z#ᛙv#n4+^]mxh;C qK" 94`*bEu96E\Dvߝ` MۭS(`ew*I: ɥ\;Jmh2E<^Q cR:Ii~)~ . 0c1=KsY/rǓP~OH&;dAc(}њpv؉lZRK?Y3}2s=yy1CLOT-,e&Wg-(Tjf5e)KzCԡM};@fJu&ۡu)KNTn5w՗" }ͱBz7i 5ѺYeFMn$ɶn0$D`oi=)#"nZCi+BC7_'ċ/+=̇MZ j8 JUGur+I3ɍڅpy&ܴ&IM'%h!ͱ3486oȩܴ^i z#oA6EŊ7(\M[BkՑ<=|d >oM쐞_Q;lwXFCBZv&N:LQv{-F[/ք5dvVevI2Z0hᵓ]RV5lU)ק}p0Xt"V&鱫)>]V:ZSt,y]#Y^p9MLbRRI@kڒzh-6@!FlhZ`n(E ڤ/Rm,o"/U)Fi=)%2YDƁab?i]~Fx %ђ}r m)EQ*9맽N]C[ڦ+y53z2S97R-"n%:vMqӛEv6b(G6i.ՠHidkM$K*i:7va9RqG䪬7[+?Yb~W,I /9y/>nZsEC[wDy\1vfC%UEmOԴ~H(&4`L԰Iq@7󳸤,V#bc+{Z&EHB*Q%-U>\>O"w8o+'q0͑l:=7/nvM{sk9)MIz8 '/Kn֧bmi@N,pF;dl4~'PKR-קT"!3kp|:wLuЍ*5;Rw=Bz9{tH,[8T+ u(AD=B?B\=KKE[!"sc3+X""IѬi-ʩ|hJkh [YYZ*>+TND8PTVDS Վi{-[<ި$61T?>]ӪۆĄ RED~Em:Q+o Y uѭ3#8LKm>"midh\[}?ux+R|h=ѩmBHp[1Z=gFt1PDoah {V]CC7}ju&kvX\"h/OݖkVr)폡HTi4z8~QZɘҷQ<0BI="`bC:qaلP>~JZE}+~FSmVt $yuG݉f#)u B\V>ؠqO[d^4//vѭbB4b \4`˲ 7ě9׺-7l9JxߎOEȱAi5U*4.o{jGUԠrC!1n"]ݑVneG|y5'뀋mނY߄O7N>Yo7juA˽9#Tu(Jr1!FchMکe6E5 zw4-EhD' P(v nNbl/nV7i6,(/ h̅nd TG[`nB58B=w:j MwgR_ln* ~/gPҢhcչq17d0-IFv4[6!5N4ō# jײ_x`hϛMm'= R{Ix 6d5`- 6i\0d!'KFޢ.$ 4Ѡ.)\0F. *.a/CێqLt19ɇZ+CҳC+3?GlD2 o)u:;F2ʠf&aBo7m*J`fP;qc,7z1TꪠKxƣiR+r&Pu,5Ů"'uź՚@wږ"?߫Zdx_x7djӕE6 f@&Nf)ZBpsfĢ'Xj-G\ Zv).UD%2]ʮͩ =r)Cz[OVY$3r^ <:hgnҚD3-ao8d(18`V=eͭ}Ť#B9i?4rPa/g(u! @S)i#r/^D'ުM^C30()9rQg;L)1[ 9a)YU3}o\;>VgԞTUlI+=ۮ!v$ˡ)V9n]neS}]R}Ek \pc%Zn߮j֚4iHj_f=h;}y>v:MuNZmRryo++ւ-#pI=Feċ\^o2(T'bSɒUx7 i$aCJVmTkYV7~zj!LH*Rw\.RcJ+Lk>)NH^JՂeK-IO帣5bאnǏU2?px .kq ˱|7XR%Uߦ)@OOd&at)RiU\riN-OqKN}K ג̓|j~~W"gW])]ON/W2O?ZQ+6=!)Ntwj,®KmSo9n,KKP2Swcj1qje/VP=r\d]zxYW o]̴櫊In)4L%/pQ-⚦wDI`JО IKH$AA@,'^t"HmCʮ>4^V$Ђf)Z#~x<,gz0a9{=oM75bv$픞DZn7DŽ?S~"Ku'+2޴T -L̆K@LDFlmYe_PÒ=W`NV@8!]ݺ|u56Qv㓧ͧ0zK+Yfݴrz}Һ+Ji2*]D'JZЈU=ln)ěǮ4SNKډMXCb*dO.d5d~N|z`j7:"v^M6Bbۗxٔ,V*&phR,oD&T^;Joj}]G34x6II&@KjeR|Y ovEnoB]a)4TXΗhړ)vGK."Nʌ}gԠ=.GIxw*7hL}8eM!,^'>IwϲJsΝB=xK[hYP(YKY1]NS+ MFwx47V18dC@Ftnk| ]-Km+)=#3ͽoOnf]iUxj 7GPZ ތzHSpޘRװp»YM4tRݥ7?N.f.)IX&XXѭGLԋ-FLn|}/vKSS4.!߃=5ip>„iZ 5"3) f=n6dYfCŃ*+RC2[9RFVF@5{VX8ܲ4) ܘ;y պF۔6 )3A-F1-UB wS+kʁfց2Zf*%WDV^QY:XM׋xQQIMz}Yڸk7ew;-Xh:/UZ1Pw>fKCoc|3l} ^NZTK _&øVdI;ӥM1ԃ4a7YQ·Lu9"Vv#VieO\XM\΋ߌ6 YV&}h^š'C' 2BǪh^f Fm*^7,{ T[Nޖk((wn&a|4'"uY uUHɻhPna+b"v݅O*#|P^-=^/C2 r@L릾Oe˥l.ƴ)6KޭC)k%eIƒ(b`&V<;)EجQƎC=¹NJ^nVB.5/V,ݼ%Бwk~ːd5Q bן ͉`XDǒj( \rXutF\fA^h`r-Մ(Q2 )T%eHօPLҷkxQM>Vl,+'zEOŘYR^#1B; TMH>iCSgWF:7bUY*WPy6ϻB5/kZc4bފnzh>Eۢ܃9UqTI^",bM+`]B njVՓ_+v;β'A^qzI}|K|:^u{v@K"%B.V  Weg,fu%Z )B^S=wxQ;HpD(4A@nb#:UR ix&Kۇأ-eDm@mA$z-(߱_Ji>vG'RrDʿwt@aꁏom& Dyܭf_f lTT#[UVȒJ1^Yl)K]buU/$_r 9M5p!Kɘ;Ob `G#8wl՚z.on+׈R}/U3qT5n-|Gn"TEM1źa 7;"E ODMY(QHm!n ) 8 C~͵zDcY,?֔-qh>R!/M-Ȣe-gsm;s+%sR/&du{Sƽ] =2*VnM m@r f(llunhkXhMQH(nVAD 0Y ?Ăf%o $??n/I1q+cGb0&uכl_: |LR&jL;ndԘ㋁Jxg.ie~V&,TMK8EۨF,2 VNyMȞ[z!]POBS٫ШMe2Y!Cu;ZB1\tv}AGJ@^B?6%d'&J"TvNªN.)64$o+PHS~G#ܐ/"BInMRjjK^`6TRΚR'Jr$JHf M)~ʡPG؈Dm&7*j^,+%;MvVv3bi\ W ;RjY_R##Jol( S-Ih0/*Y|NtWxg$'v;+;ܒBA(Vلȧ2.98d P4Ct 1dQ=ZSQ.Y}R7 (h0g*/RZ47kӚɘJcPmRJh&Mhޭj^PPPRN%%qdkc c`ӵ`J^LoTPxb #i'LMIK^YWhZ?^]yGπTT~ɇ~9?q^g1'㭼 dȣB TKiHKFm-Y vjRAQZvY;6qk5 ;^oܬ 7$̜K!-\Tj1$[;sr$[W:R`:1VsXkfvp>`Or ^Z0pI%q̬}g > ` AP$?$ѤחI$f2#lRK=hꦓ~DR 3ULִQWW]>J4咐/` D.N+ioĉ@)L̎:Ȧh6w)+ޭ7x;$Bєwp‹b}3sC m\ T̓\ɡ#z^K sX$hƲ dv'DL9Bj!-YI44i*CKq(HҭPxlZ/C"ė^wz2통X&.MNM9 ͔ٙy`k's2ӫ^$.»H nHD b ;m0l?E 7yER>ԕ@MU5"^*+w13owV0m3>ᑮEk_!vR0vǓ%vl]O⢅z Kc b W#r j(a{D-J\JڀRuҶX7y)~@Fpc& OH*F&fiMt,bjԀ%@i^F$R, 1$_'it- Ar>0rN]qXyCrZ6k5陛b;)ufTEX8iP{SۂR+-r(Wl~WZI򠃥ޘ'u=T4YE fhpk\a̴k-T$'x0iR 9$Ic5 QDgs(7WҢNOKQcѡL ![ZN=5D69jscwSJE{*_. ZNyrw Mz?JQ'}|<9T>tnBrCvZmr!e#fhFK%=G#u&բB[05qW,!,jQ$KxCa UTڒzJļRm% 'AA dǂ&c:S`%j%E^RnhM@fM4O碖Ѯȗ w,]HΨaŔf'ya6]*<3CfO ^y%?BQkg(\%Yuy%)+Q.cP+ikՔ,Fs9p*XtUdhH ,<>5~%A02o]yD(3R.(S#䔇P d"N*PCT^(ˈEAr*eE<)MtyNKn/H*g_ҦjbFR6rg.H5Ê˩I7%Ҥ7"M%?IrPu8KtJ<_ƪ:%DsP͈jԺVkM9g+JȚ'ɼVU^tGF Z't72<treWxNTd:0v 9WCKуFIVUc`KNZSy"= _rI0 ZRd >R,+JtSdCn& AjdK<\wr*j)Z;_a+_`/i2?պ"LMÄy5ܫrjRدrS*N]O'"촆fqj^8K#8Yz&Zꡥu1LHJ~y6TubT !qDrФYL[e(FM]\6Au /08OzǃJl5!Ky(DKub/jWư:mF\MzWM؝B!fG*Ƈ#5%dߕ٢F Bd:lW.jaoqu%%f!ip1Tgi|X7*1|m^O'K1þJ°jd%{լzzMf_TApk9qk0D";_KD2gRv\bI]B5RiK̀XԄdJlb"6<}SXid ,W% JښvR򂮒HX"ѓ!DM9QBid#r"e<--SV' -Lwtߡo7ڮ6lI{]kSp%lҦjSvVNfr'܈3DYi^֍õ9Z#sD?hR}8nM [!R@MdO+ke@8V2_x"-S jj4 nθkBaK k@0 /dEDQEH/(r%ʆy"N5^5KJl kt+`ٱ@*-גȗ+5hoޓ6B'hK n.<+cQ^PLPO9jM.=>,RmR/$ Ia9FPL]oCtymg t+y=ݺAܭ4n А )ԺIDn GUfFmF|AB @_ԮHZK ("aX2>p6oWN`+OǴRDI*"VAk :2al4QpxWВZF%P-cNj-jB8 Jno2rx5)Y2 tڡ: !KvUtSXT:cr5b֘փ;e<__/mFԲS\\/i7Q?-EܼMA@S7y)>:=>Y7LRrXqGZd'KVOICDFkrؒHkSOZTX؉۳.,D Icp6`]n,!u\0ZBY,)%SN1*ֽjaC$J+`~ʲP"ortE@5)%E,*Kb3 Ni@ !oSn;] 7_-?^Jϗk[[2KIψKE9t-f`M błP-E]/tSfaKСALMl eX(`Ӹ;,yEgDaw-HhӅY(R%5*dwՄ Aà …\Pa]!P#*EZ!T\Z]v!0P T}i5b5֒B*$ETƅl.]EM[xZ4A]iݙC(ݝUn~mdMzz6F1WUij`}:1 'Y/CuMt:!Ÿ[;*K{Ss!x1coZ&TBF=)um>PŘB#hET^MK"JB]LnPKR`A]ZMEĒVu&rPB%@JQe &(EK ԴE*vk|v{Ev{IUlÒD҃";M)rI_RFtL#|٧}k[$iDjnT5p/Mk3喇\nUnsV頦 &e0)ˊn;2~MRRqSBK!|#LhRIAʦIE.a-oRTvjLbEZbZTUe jbIUY8 +-RBdX qBCj]jK{J4.0tudPz.,yI4ȡT !`$mKloj/ e!ul/zw_/c,4sWu6+Ԥ]EMۃ=ſt[ 1uU[G&vn$]Ccho7t.mpPkqrcƈmJQ1[lhվ\ڬ&Fb?t|j1K_WSLL~,?U=7lhW/;٭*\v;5}]nAq8p{N8j2Rv2y^&~KOPSK,i0Hro\-0S;|@5r'.]Ƚ^ϵg懔6b{D\7vpK}J݅gG,\/ZibM֍*kĚ< OKC"+b-Ŏf`$PR 8`ENh keP鋛ՋN$㩵+DlT FP!5F8I ^j3V[ 3VĖ]E@J>7ڋ݊̾Ԧ|_>~mtմogɘ&wn82U Kg8ãXVG {`-Ok5m%Jg*dSBN leLF*P%AJ$ uSJkM*$2u5982X.*j*d#*ͩ ӫ!Rl ,ѬVDzI-z*nr[-GTֈh2CYQcnGMVsgS- VMocF13oo+:1Z]hA!vqՒ *P46nnay94/sSNfEn X]h%Y#;wڑ?imj;VzQ/-QM,Ty;Z`M4Y.lD.'e򒘞 p6e92mmr RNB`"`*S~Z@7%i xD5tb9 tw e;"߉ޕij%0v;$@-ը [x%"Eu͒JkiM:ܪ&lr:dX_V4U~Uku[pӣQC5׈F݋q6F|=EFoRKv#jAh28=5+-xFf|>ݪT MNM3#jh*+RQlD.H"䆊XD&T5IHM\Rdi8.R4+}684T;Zȶ$J8`]I3S1Y&Tfrib}E=hCNn|~ZZ;UF\&|BF/Lw9KEÇTUNʿS `&9 ]7a<_`Syvw}fi5Gd=]]0-urNΫQ}jLZih['=ڙHy=sPj)/]**]8bəZVxE*a®\A6% ^JdCl ¢,J!a Q<=A!RZŋޙ lY!?)+7uS_Lsx=uUK%qFQwN]RL}⾄sr?+߼[oAZy\^}E;鄕.)8$zDEG>5hoSM5Gg=uFN+Շq,D“u2YUĵ7]e+ J"%2 ZT+ZT`t)]W+$/A $*]E!&j JHap'MM:HSK6)PK<ʿi&Yήj{x ϋew'+nvH9rMK( Ѣ4/օ3|TESpY7?x6 +dv;OlUU*!(еDin'穾٪ ;Ʊ־=>}mwc/@b|\RMYn+yV^(j:k1FAu";W1iJ40RH*aO@TShi@)HTiSZ?PBF~.D\XIlV`E.Hbz/Eȣč؈StO|"D¥h _Mںؙ8كQqлRꧏSVԖXT?FC=}ѲpX =&0{^*P;ɵYL-7Z&WϪZԎ3}EĒ{ϚE9nVzlj+=d}rNjU9d}egV0m]>%Qdy+cV`4bBQhP4$D*=  Aء$d,pY 6K/DIt0$QñimͶBԠJ]s|Jȗ \jMެ-^(W̝Gu-TnSMJx}( Xzyf95\X5|?nT,+G>pgSd-p6}]{"fB65&uuz-i }YOuZ9ł5Xr kL t%{FSϕ7h妐;C/f:i 42ALc9 `U&e6)P6S$)ϓl }ӫ8^\oS Mۮ&ޢ)T埲ϪEx~Ѧz'NlbaMV"@UmTN1:\㋮*.<{U wu|zmktT*H]kR]䊹ӳqݘlﮣS$֎D| B,e%=&:˫ 3ˊf5cZˆI%PP@@S_EËPsC-!Ȑ@ E<$r7U/2>pi+GmcZENڰO⍹A]Z=%ݴ W7L0t;J` <G=j[51fm'/euUk*ӜX.;R$I5LPW3+^'~axylBTh7)Y[VG_mOmxĎxv|a%'1P{ß7 *R%ʦ6墺bI4XF|,XhoʉwmlIPqJF_κBr-b(ߔb)~w;L@$nMi6)\N]v hNmin.[yWS_R ;''qmRﴝf(wC̟_(i g'/Yl_TjNmx=]5#$`Q'(3h5QMABtp$hHk4oܥoj< WE0ge7ԼZp7;&,u%6 oEЮ$WzE[vn^`ŸWb*8N"~S,SD~5nF[  G %G< JeR}S|7T$:c>mdAxFEP޽gq-NLT.sOTwr(`ftpt{8R`6=.˱ R2āIENDB`aqualung-0.9beta11/skin/ocean/fx.png0000644000175000001440000000074210612341735014273 00000000000000PNG  IHDR i pHYs  tIME  8N1YtEXtCommentCreated with The GIMPd%nbKGD*FIDAT8c`z@ֈA,60AmvҗSh[WtJǪAbZޙ3@. +qK o<鶳W i@,!@Am:tlXiߚ]߿H2b DU?s þ2H/ci{|LBfM`N[9dl`@%İ ȁRosj̋ b؄Ia\A<Ù t97 a&NYP"hcj^MFVB5C ~c}IENDB`aqualung-0.9beta11/skin/ocean/ms.png0000644000175000001440000000170510612341735014275 00000000000000PNG  IHDR i pHYs  tIME u"ltEXtCommentMenu-sized icon ========== (c) 2003 Jakub 'jimmac' Steiner, http://jimmac.musichall.cz created with the GIMP, http://www.gimp.orggGbKGD*IDAT8˕OSQ+Ј.\BLL\ qk.A(C(2[4$C)eT"F… Ê9%{9>8U4-.@sxE+d(B :\дΝ(6V(R\Q{՝ K(FC$-tp.,:9> q 񮦾%L+oI5wyq50, v`_Ol:^њ4)G`!/ɥmh ӟpaD 3v-c^bg̑f7,01;TEP׼_B}G؇qg|"P=BR/\"{)`] k͐MΩ .marm!PYKXAg@^͔ %A`p+Ô1eʭePB+;'֩><6u|ڃSP$^N.-aWZEOʫ9g\])jqr@mR\,=Pw: Y+Y 遉`ҥߩ k1m Kus@>.3|L(80*ct:kx_|;\x&T6 `O /1j82[})WR7D54VM~ciM#W]ˇiL7 m8́">DeN\GEGTVHWPz}hNxP(@aPՃ: (mB [ԁ$l"+ 2Hm,ȑUKj.}(rJ34V+mflc5xz/mUf%Vw-ቴk&6-Nl?5r˗>NF Xɖ_$BY&>m84!2I5X}7\4\o wpuV4IENDB`aqualung-0.9beta11/skin/ocean/pause.png0000644000175000001440000000111310612341735014764 00000000000000PNG  IHDR pHYs  tIME %y ?bKGDZXSIDAT8ՔKKQ3TP~@-E~`Y=, `zkJd2fQjQd#Ijgh-V3 X3u[a~ssy!O(&i_I^56WO B# (TEjpE`rqhc\],.1hỉO\R;#pKGDս+̻BP7^3Œڙgc j2fE(W.ݠ} Optq'zHm55 ]ܓU@r(( QGIS̹9I 4N_uk0ZuI7|I^k[ANhŀOTİy CshP\a兯Ta1 rD)GUDV"_Nn7W8FQkAI|(2B4%a_CXn6G%[?8'3sBIENDB`aqualung-0.9beta11/skin/ocean/play_pause.png0000644000175000001440000000166211062755225016025 00000000000000PNG  IHDR gAMA abKGD pHYs  tIME3/IDAT8˭k\Uϙs2&41ܠ-(B)BhD# kl^P'!xyZHX1)5&8Cg2ۗLD6{^{ތLJ" r3Z bMPz1:5zxJanbFOO`aq بhnV1H~2>t$տPT})ʹٽ:4*ܓC%JEޠ 8Qouri#`0lNinuב,S0z4VWZw&Ytg?g2F3btԞm D󬵦C fy8|}H}(lW`_f0ۋe0 iw& dLa #<^x:{H?rap\Q0 a Z1l4\ \ONq0c67=\7DNHj-?K ת,-hXpzo/ZḼF z;T^Zqi7Z R,[\/7 d^)EBDbV*k'Hr%U ӑݡ,lS@NRgxYdfrGR^})NA })bzPjve77H=q!^CRի3C -RݟF9؇uݭ5`q#: =_(.Ka);oΒmȠ6ט$z<.+nqgmAfv@[%LW]ZC8Z79 :`\ŷu!^#j 1d"56 "ֲ0T*ɥ'ՕJc?wnϽIENDB`aqualung-0.9beta11/skin/ocean/prev.png0000644000175000001440000000140410612341735014626 00000000000000PNG  IHDR pHYs  tIME 4ǎYbKGD*IDAT8c`T@ڊAʎ H3a P܏")Q!A/2K\2ƪìE<~H.5?8{zEAl,^gSͦ*=®f`ׂ1,Y>А{O^yϒ FELr.k}*_3}yN_^VoW$|͘?m +yg߰8 dgItoZVDǔ/8Xw]w7owۼ8\(a ŤMwK^2=FYgftbsWZ?8o}2&O^?s & +y-1&{b!m@~Q282"@ExF`VbQjlo 4eP#XF CDpldu)fO.뿾kQmZXܷ@1@]G߽E`=@00c%VaYY0_ fUMp*jSp`s+;SʿEHDB!Cbqf ir||ۘIENDB`aqualung-0.9beta11/skin/ocean/repeat_all.png0000644000175000001440000000026210612341735015763 00000000000000PNG  IHDR 2 H pHYs  tIME *WbKGDZXS?IDAT(c``aaPRP(1A%I2AD244R.$ )tcIENDB`aqualung-0.9beta11/skin/ocean/repeat.png0000644000175000001440000000030210612341735015126 00000000000000PNG  IHDR 2 H pHYs  tIME *"wbKGDZXSOIDAT(c``aaPRP(@%.ʠE-#F@0Pf0 y 4>qx>$+{ IENDB`aqualung-0.9beta11/skin/ocean/shuffle.png0000644000175000001440000000034510612341735015311 00000000000000PNG  IHDR i pHYs  tIME  5YebKGDZXSrIDAT8c` @z "3`1|wPS$(dTa g8@49.e@ $+ieyJgćVQa6S4W:Û٣)tG6|bIENDB`aqualung-0.9beta11/skin/ocean/stop.png0000644000175000001440000000140410612341735014637 00000000000000PNG  IHDR bKGDZXS pHYs  tIME CIDAT8ՓnU:>s3 0 ,yd͊aCބ'@% Ea[d1h%CHb dQ|#Ϲ;\䧧}|6OFszDq>&6u;H3,^P&nZRB`W5}!k b9 J >xMufےs1Y6W5?bV*>}"l>c4+!A5SĐnRєwL'%%|^ռRZEyR x9)eS:}BfP=YQbΣf.4,kֳ7!F]14IjBHhv^Xo@[i/:Ŷi>0ZbUbXRʴMGj,/_6Zd^8F_١{IENDB`aqualung-0.9beta11/skin/plain/0000777000175000001440000000000011331334362013244 500000000000000aqualung-0.9beta11/skin/plain/Makefile.am0000644000175000001440000000012210715346601015213 00000000000000skindir = $(pkgdatadir)/skin/plain skin_DATA = rc *.png EXTRA_DIST = $(skin_DATA) aqualung-0.9beta11/skin/plain/Makefile.in0000644000175000001440000002247011331334253015231 00000000000000# Makefile.in generated by automake 1.10.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # This Makefile.in 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. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = skin/plain DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = SOURCES = DIST_SOURCES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; am__installdirs = "$(DESTDIR)$(skindir)" skinDATA_INSTALL = $(INSTALL_DATA) DATA = $(skin_DATA) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBAVCODEC_CFLAGS = @LIBAVCODEC_CFLAGS@ LIBAVCODEC_LIBS = @LIBAVCODEC_LIBS@ LIBAVFORMAT_CFLAGS = @LIBAVFORMAT_CFLAGS@ LIBAVFORMAT_LIBS = @LIBAVFORMAT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ var = @var@ skindir = $(pkgdatadir)/skin/plain skin_DATA = rc *.png EXTRA_DIST = $(skin_DATA) all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu skin/plain/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu skin/plain/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh install-skinDATA: $(skin_DATA) @$(NORMAL_INSTALL) test -z "$(skindir)" || $(MKDIR_P) "$(DESTDIR)$(skindir)" @list='$(skin_DATA)'; for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ f=$(am__strip_dir) \ echo " $(skinDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(skindir)/$$f'"; \ $(skinDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(skindir)/$$f"; \ done uninstall-skinDATA: @$(NORMAL_UNINSTALL) @list='$(skin_DATA)'; for p in $$list; do \ f=$(am__strip_dir) \ echo " rm -f '$(DESTDIR)$(skindir)/$$f'"; \ rm -f "$(DESTDIR)$(skindir)/$$f"; \ done tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(DATA) installdirs: for dir in "$(DESTDIR)$(skindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-skinDATA install-dvi: install-dvi-am install-exec-am: install-html: install-html-am install-info: install-info-am install-man: install-pdf: install-pdf-am install-ps: install-ps-am installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-skinDATA .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic distclean \ distclean-generic distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-skinDATA install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic pdf pdf-am ps ps-am uninstall \ uninstall-am uninstall-skinDATA # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: aqualung-0.9beta11/skin/plain/rc0000644000175000001440000001647210634553071013526 00000000000000 #---------------------------------------------------- # plain skin for aqualung # # icons by ironya #---------------------------------------------------- # --- windows style "window" { bg_pixmap[NORMAL] = "" bg_pixmap[PRELIGHT] = "" bg_pixmap[ACTIVE] = "" bg[NORMAL] = "#dcdad5" bg[PRELIGHT] = "#bab5ab" bg[ACTIVE] = "#bab5ab" fg[NORMAL] = "#000000" fg[PRELIGHT] = "#000000" fg[ACTIVE] = "#000000" font_name = "Sans 11" } style "main_window" = "window" { } style "plugin_scrwin" = "window" { bg_pixmap[NORMAL] = "" bg[NORMAL] = "#dcdad5" fg[NORMAL] = "#000000" } widget "*GtkWindow*" style "window" widget "*Dialog*" style "window" widget "*FileSelection*" style "window" widget "*playlist_window*" style "window" widget "*main_window" style "main_window" # --- common widgets style "button" { bg[NORMAL] = "#dcdad5" bg[PRELIGHT] = "#eeebe7" bg[ACTIVE] = "#bab5ab" bg_pixmap[NORMAL] = "" bg_pixmap[PRELIGHT] = "" bg_pixmap[ACTIVE] = "" fg[NORMAL] = "#000000" fg[PRELIGHT] = "#000000" fg[ACTIVE] = "#000000" font_name = "Sans 9" } style "view" { text[NORMAL] = "#000000" text[SELECTED] = "#ffffff" text[ACTIVE] = "#000000" base[NORMAL] = "#dbdbcc" base[SELECTED] = "#306090" base[ACTIVE] = "#b0c0d0" fg[NORMAL] = "#000000" fg[SELECTED] = "#dbdbcc" } style "scrollbar" { bg_pixmap[NORMAL] = "" bg_pixmap[PRELIGHT] = "" bg_pixmap[ACTIVE] = "" bg[NORMAL] = "#dcdad5" bg[PRELIGHT] = "#eeebe7" bg[ACTIVE] = "#bab5ab" fg[NORMAL] = "#000000" fg[PRELIGHT] = "#000000" } style "progressbar" { bg[NORMAL] = "#dcdad5" bg[PRELIGHT] = "#4b6983" fg[PRELIGHT] = "#eeeeee" } style "notebook" { bg[NORMAL] = "#dcdad5" bg[PRELIGHT] = "#4b6983" bg[ACTIVE] = "#bab5ab" } style "entry" = "view" { font_name = "Sans 10" } style "combo_box" { text[NORMAL] = "#000000" text[PRELIGHT] = "#000000" fg[NORMAL] = "#000000" } style "menu" = "button" { text[NORMAL] = "#000000" text[PRELIGHT] = "#000000" } style "spin_button" = "button" { text[NORMAL] = "#000000" text[SELECTED] = "#000000" text[ACTIVE] = "#000000" base[NORMAL] = "#e8e8de" base[SELECTED] = "#bab5ab" base[ACTIVE] = "#eeebe7" } style "scale" { bg[NORMAL] = "#dcdad5" bg[PRELIGHT] = "#eeebe7" bg[ACTIVE] = "#bab5ab" bg_pixmap[NORMAL] = "" bg_pixmap[PRELIGHT] = "" bg_pixmap[ACTIVE] = "" fg[NORMAL] = "#404040" } style "loop_bar" { bg_pixmap[NORMAL] = "" bg[NORMAL] = "#bab5ab" bg[ACTIVE] = "#868074" bg[SELECTED] = "#4b6983" fg[NORMAL] = "#dcdad5" fg[PRELIGHT] = "#eeebe7" } style "checkbutton" { bg_pixmap[NORMAL] = "" bg_pixmap[PRELIGHT] = "" bg_pixmap[ACTIVE] = "" fg[NORMAL] = "#000000" fg[PRELIGHT] = "#000000" fg[ACTIVE] = "#000000" } style "nostyle" { bg_pixmap[NORMAL] = "" bg_pixmap[PRELIGHT] = "" bg_pixmap[ACTIVE] = "" fg[NORMAL] = "#000000" fg[PRELIGHT] = "#000000" fg[ACTIVE] = "#000000" } widget "*ScrolledWindow*" style "scrollbar" widget "*plugin_scrwin*" style "plugin_scrwin" widget "*TreeView*" style "view" widget "*TextView*" style "view" widget "*List*" style "view" widget "*Notebook*" style "notebook" widget "*Scrollbar*" style "scrollbar" widget "*Separator*" style "scrollbar" widget "*Progress*" style "progressbar" widget "*OptionMenu*" style "button" widget "*Menu*" style "menu" widget "*SpinButton*" style "spin_button" widget "*Scale*" style "scale" widget "*AqualungLoopBar*" style "loop_bar" widget "*Button*" style "button" widget "*GtkEntry*" style "entry" widget "*Combo*" style "combo_box" widget "*CheckButton*" style "checkbutton" widget "*nostyle" style "nostyle" # --- checkbutton widget "*check_on_window" style "window" widget "*check_on_notebook" style "notebook" # --- main window style "viewport" { bg[NORMAL] = "#dcdad5" bg_pixmap[NORMAL] = "" } style "time_viewport" = "viewport" { bg_pixmap[NORMAL] = "" } style "title_viewport" = "viewport" { bg_pixmap[NORMAL] = "" } style "info_viewport" = "title_viewport" { } style "big_timer_label" { fg[NORMAL] = "#000000" font_name = "Courier 10 Pitch 12" } style "small_timer_label" { fg[NORMAL] = "#000000" font_name = "Courier 10 Pitch 10" } style "label_title" { fg[NORMAL] = "#000000" font_name = "Sans 12" } style "label_info" { fg[NORMAL] = "#000000" font_name = "Sans 8" } style "scale_pos" = "scale" { GtkScale::slider-length = 31 } style "scale_vol" = "scale_pos" { GtkScale::slider-length = 11 } style "scale_bal" = "scale_pos" { GtkScale::slider-length = 11 } widget "*time_viewport" style "time_viewport" widget "*title_viewport" style "title_viewport" widget "*info_viewport" style "info_viewport" widget "*big_timer_label" style "big_timer_label" widget "*small_timer_label" style "small_timer_label" widget "*label_title" style "label_title" widget "*label_info" style "label_info" widget "*scale_pos" style "scale_pos" widget "*scale_vol" style "scale_vol" widget "*scale_bal" style "scale_bal" # --- music store style "music_tree" = "view" { font_name = "Sans 11" } style "comment_view" = "view" { font_name = "Sans 11" } widget "*music_tree" style "music_tree" widget "*comment_view" style "comment_view" # --- playlist style "play_list" = "view" { fg[SELECTED] = "#0505b8" fg[INSENSITIVE] = "#000000" font_name = "Sans 9" } style "playlist_color" { fg[NORMAL] = "#000000" fg[ACTIVE] = "#00026b" fg[SELECTED] = "#0505b8" fg[INSENSITIVE] = "#000000" } style "playlist_tab_close_button" = "button" { bg_pixmap[NORMAL] = "" bg_pixmap[PRELIGHT] = "" bg_pixmap[ACTIVE] = "" } style "playlist_tab_label" { font_name = "Sans 10" } widget "*play_list" style "play_list" widget "*playlist_color_indicator*" style "playlist_color" widget "*playlist_tab_label*" style "playlist_tab_label" widget "*playlist_tab_close_button*" style "playlist_tab_close_button" # --- plugins style "plugin_name" { font_name = "Sans 12" } style "plugin_maker" { font_name = "Sans 10" } style "plugin_bypass_button" = "button" { bg_pixmap[ACTIVE] = "" bg[ACTIVE] = "#bab5ab" fg[NORMAL] = "#000000" fg[PRELIGHT] = "#000000" fg[ACTIVE] = "#000000" } style "plugin_scale" = "scale" { bg_pixmap[ACTIVE] = "" bg[ACTIVE] = "#bab5ab" } style "plugin_toggled" = "button" { bg_pixmap[NORMAL] = "" bg_pixmap[PRELIGHT] = "" bg_pixmap[ACTIVE] = "" bg[NORMAL] = "#dcdad5" bg[PRELIGHT] = "#eeebe7" bg[ACTIVE] = "#bab5ab" } widget "*plugin_name" style "plugin_name" widget "*plugin_maker" style "plugin_maker" widget "*plugin_bypass_button*" style "plugin_bypass_button" widget "*plugin_scale" style "plugin_scale" widget "*plugin_toggled" style "plugin_toggled" # --- mod info list style "samples_instruments_list" { font_name = "Monospace 10" base[SELECTED] = "#e8e8de" base[ACTIVE] = "#e8e8de" fg[NORMAL] = "#e8e8de" fg[SELECTED] = "#e8e8de" text[SELECTED] = "#000000" text[ACTIVE] = "#000000" } widget "*samples_instruments_list" style "samples_instruments_list" aqualung-0.9beta11/skin/plain/next.png0000644000175000001440000000062410612341733014647 00000000000000PNG  IHDR7bKGD̿ pHYs  tIME %!upL tEXtCommentMenu-sized icon ========== (c) 2003 Jakub 'jimmac' Steiner, http://jimmac.musichall.cz created with the GIMP, http://www.gimp.orggGIDAT(c` Y~qY4 _[!B^ C&_J0,A "]>%LcS„`wu`V< b3{Tsl pICf``a``@ASp YJy&ZQIENDB`aqualung-0.9beta11/skin/plain/pause.png0000644000175000001440000000052410612341733015005 00000000000000PNG  IHDR7bKGD̿ pHYs  tIME %( tEXtCommentMenu-sized icon ========== (c) 2003 Jakub 'jimmac' Steiner, http://jimmac.musichall.cz created with the GIMP, http://www.gimp.orggGMIDAT(c` X4 _[ٔ9RP5^ !d6D B-aX7 WCF$*G$(IENDB`aqualung-0.9beta11/skin/plain/play_pause.png0000644000175000001440000000063511062755225016042 00000000000000PNG  IHDR7gAMA abKGD̿ pHYs  tIME 7>rtEXtCommentMenu-sized icon ========== (c) 2003 Jakub 'jimmac' Steiner, http://jimmac.musichall.cz created with the GIMP, http://www.gimp.orggGIDAT(c` X _sج~Tgbf*a \T%L-AS„i#&l._ S„s]VGA!FF ^AX0cັ*%$!NC[)Q,M_@IENDB`aqualung-0.9beta11/skin/plain/play.png0000644000175000001440000000055610612341733014642 00000000000000PNG  IHDR7bKGD̿ pHYs  tIME %{tEXtCommentMenu-sized icon ========== (c) 2003 Jakub 'jimmac' Steiner, http://jimmac.musichall.cz created with the GIMP, http://www.gimp.orggGgIDAT(c` *W&dίJP, % "mJ0ex2g`dĩ4 t nbt#i8't84RIENDB`aqualung-0.9beta11/skin/plain/prev.png0000644000175000001440000000064310612341733014646 00000000000000PNG  IHDR7bKGD̿ pHYs  tIME %AtEXtCommentMenu-sized icon ========== (c) 2003 Jakub 'jimmac' Steiner, http://jimmac.musichall.cz created with the GIMP, http://www.gimp.orggGIDAT(c` X4 _[aRl3c`````b#!<&33`6_ ,&l:S΄_6EȖJA֍%WXGs؟J89{q*HB*$h@h_<yA HIIENDB`aqualung-0.9beta11/skin/plain/repeat_all.png0000644000175000001440000000026510612341733016002 00000000000000PNG  IHDR 2 HbKGDop pHYs  tIME "kBIDAT(c``aaPg``OE1 *I.e"F5++9'`i, rÐ*$'n ,IENDB`aqualung-0.9beta11/skin/plain/repeat.png0000644000175000001440000000030410612341733015144 00000000000000PNG  IHDR 2 HbKGDop pHYs  tIME !,oQIDAT(c``aaPg``OE1*I.OtqVV ,j6E0!b4!nC$ަ$+N>IENDB`aqualung-0.9beta11/skin/plain/shuffle.png0000644000175000001440000000036210612341733015324 00000000000000PNG  IHDRrP6bKGDop pHYs  tIME 0(IDAT8c`  100'3`1|wPS& ըi+!yG@fLIjXkeyJgćVQ1Œv)YW:Û٣)C =E#¶IENDB`aqualung-0.9beta11/skin/plain/stop.png0000644000175000001440000000054610612341733014661 00000000000000PNG  IHDRabKGD pHYs  tIME #7^tEXtCommentMenu-sized icon ========== (c) 2003 Jakub 'jimmac' Steiner, http://jimmac.musichall.cz created with the GIMP, http://www.gimp.orggG[IDAT8c`02000022Jw^z100'?L/ AK,!肘>a0j0j)As4-8ǑIENDB`aqualung-0.9beta11/skin/woody/0000777000175000001440000000000011331334362013302 500000000000000aqualung-0.9beta11/skin/woody/Makefile.am0000644000175000001440000000012210715346601015251 00000000000000skindir = $(pkgdatadir)/skin/woody skin_DATA = rc *.png EXTRA_DIST = $(skin_DATA) aqualung-0.9beta11/skin/woody/Makefile.in0000644000175000001440000002247011331334253015267 00000000000000# Makefile.in generated by automake 1.10.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # This Makefile.in 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. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = skin/woody DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = SOURCES = DIST_SOURCES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; am__installdirs = "$(DESTDIR)$(skindir)" skinDATA_INSTALL = $(INSTALL_DATA) DATA = $(skin_DATA) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBAVCODEC_CFLAGS = @LIBAVCODEC_CFLAGS@ LIBAVCODEC_LIBS = @LIBAVCODEC_LIBS@ LIBAVFORMAT_CFLAGS = @LIBAVFORMAT_CFLAGS@ LIBAVFORMAT_LIBS = @LIBAVFORMAT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ var = @var@ skindir = $(pkgdatadir)/skin/woody skin_DATA = rc *.png EXTRA_DIST = $(skin_DATA) all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu skin/woody/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu skin/woody/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh install-skinDATA: $(skin_DATA) @$(NORMAL_INSTALL) test -z "$(skindir)" || $(MKDIR_P) "$(DESTDIR)$(skindir)" @list='$(skin_DATA)'; for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ f=$(am__strip_dir) \ echo " $(skinDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(skindir)/$$f'"; \ $(skinDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(skindir)/$$f"; \ done uninstall-skinDATA: @$(NORMAL_UNINSTALL) @list='$(skin_DATA)'; for p in $$list; do \ f=$(am__strip_dir) \ echo " rm -f '$(DESTDIR)$(skindir)/$$f'"; \ rm -f "$(DESTDIR)$(skindir)/$$f"; \ done tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(DATA) installdirs: for dir in "$(DESTDIR)$(skindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-skinDATA install-dvi: install-dvi-am install-exec-am: install-html: install-html-am install-info: install-info-am install-man: install-pdf: install-pdf-am install-ps: install-ps-am installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-skinDATA .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic distclean \ distclean-generic distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-skinDATA install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic pdf pdf-am ps ps-am uninstall \ uninstall-am uninstall-skinDATA # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: aqualung-0.9beta11/skin/woody/rc0000644000175000001440000001630010657352325013556 00000000000000# --- windows style "window" { bg_pixmap[NORMAL] = "wood5.png" bg_pixmap[PRELIGHT] = "wood5.png" bg_pixmap[ACTIVE] = "wood5.png" bg[NORMAL] = { 0.3, 0.2, 0.0 } bg[PRELIGHT] = { 0.3, 0.2, 0.0 } bg[ACTIVE] = { 0.3, 0.2, 0.0 } fg[NORMAL] = { 1.0, 1.0, 1.0 } fg[PRELIGHT] = { 1.0, 1.0, 1.0 } fg[ACTIVE] = { 1.0, 1.0, 1.0 } font_name = "Sans Bold 10" } style "main_window" = "window" { bg_pixmap[NORMAL] = "wood2.png" } style "plugin_scrwin" = "window" { bg_pixmap[NORMAL] = "" bg[NORMAL] = { 1.0, 1.0, 0.9 } fg[NORMAL] = { 0.0, 0.0, 0.0 } } widget "*GtkWindow*" style "window" widget "*Dialog*" style "window" widget "*FileSelection*" style "window" widget "*playlist_window*" style "window" widget "*main_window" style "main_window" # --- common widgets style "button" { bg_pixmap[NORMAL] = "wood4.png" bg_pixmap[PRELIGHT] = "wood3.png" bg_pixmap[ACTIVE] = "wood1.png" bg[NORMAL] = { 0.1, 0.1, 0.0 } bg[PRELIGHT] = { 0.2, 0.2, 0.0 } bg[ACTIVE] = { 0.3, 0.3, 0.0 } fg[NORMAL] = { 0.0, 0.0, 0.0 } fg[PRELIGHT] = { 0.0, 0.0, 0.0 } fg[ACTIVE] = { 0.0, 0.0, 0.0 } font_name = "Sans Bold 10" } style "view" { text[NORMAL] = { 0.0, 0.0, 0.0 } text[SELECTED] = { 0.0, 0.0, 0.0 } text[ACTIVE] = { 0.0, 0.0, 0.0 } base[NORMAL] = { 1.0, 1.0, 0.9 } base[SELECTED] = { 0.643, 0.875, 1.0 } base[ACTIVE] = { 0.737, 0.824, 0.933 } fg[NORMAL] = { 0.0, 0.0, 0.0 } fg[SELECTED] = { 0.643, 0.875, 1.0 } } style "scrollbar" { bg_pixmap[NORMAL] = "" bg_pixmap[PRELIGHT] = "" bg_pixmap[ACTIVE] = "" bg[ACTIVE] = { 0.5, 0.4, 0.0 } bg[NORMAL] = { 0.6, 0.5, 0.3 } bg[PRELIGHT] = { 0.7, 0.6, 0.3 } fg[NORMAL] = { 0.0, 0.0, 0.0 } fg[PRELIGHT] = { 0.0, 0.0, 1.0 } } style "progressbar" { bg[NORMAL] = { 0.0, 0.0, 0.1 } bg[PRELIGHT] = { 0.5, 0.25, 0.15 } } style "entry" = "view" { bg[NORMAL] = { 0.1, 0.1, 0.0 } bg[PRELIGHT] = { 0.2, 0.2, 0.0 } bg[ACTIVE] = { 0.3, 0.3, 0.0 } font_name = "Lucida 12" } style "combo_box" { text[NORMAL] = { 0.0, 0.0, 0.0 } text[PRELIGHT] = { 0.0, 0.0, 0.0 } fg[NORMAL] = { 0.0, 0.0, 0.0 } } style "menu" = "button" { bg_pixmap[NORMAL] = "wood3.png" bg_pixmap[PRELIGHT] = "wood6.png" bg[NORMAL] = { 0.1, 0.1, 0.0 } bg[PRELIGHT] = { 0.2, 0.2, 0.0 } text[NORMAL] = { 0.0, 0.0, 0.0 } text[PRELIGHT] = { 0.0, 0.0, 0.0 } font_name = "Sans Bold 10" } style "spin_button" = "button" { text[NORMAL] = { 0.0, 0.0, 0.0 } text[SELECTED] = { 0.0, 0.0, 0.0 } text[ACTIVE] = { 0.0, 0.0, 0.0 } base[NORMAL] = { 1.0, 1.0, 0.78 } base[SELECTED] = { 0.643, 0.875, 1.0 } base[ACTIVE] = { 0.737, 0.824, 0.933 } } style "scale" { bg[NORMAL] = { 0.55, 0.5, 0.4 } bg[PRELIGHT] = { 0.65, 0.55, 0.4 } bg[ACTIVE] = { 0.05, 0.1, 0.15 } bg_pixmap[NORMAL] = "" bg_pixmap[PRELIGHT] = "" bg_pixmap[ACTIVE] = "scale_bg.png" fg[NORMAL] = { 0.3, 0.2, 0.0 } } style "loop_bar" { bg_pixmap[NORMAL] = "scale_bg.png" bg[NORMAL] = { 0.05, 0.1, 0.15 } bg[ACTIVE] = { 0.0, 0.0, 0.0 } bg[SELECTED] = { 0.3, 0.2, 0.1 } fg[NORMAL] = { 0.55, 0.5, 0.4 } fg[PRELIGHT] = { 0.75, 0.6, 0.4 } } style "nostyle" { bg_pixmap[NORMAL] = "" bg_pixmap[PRELIGHT] = "" bg_pixmap[ACTIVE] = "" fg[NORMAL] = { 0.0, 0.0, 0.0 } fg[PRELIGHT] = { 0.0, 0.0, 0.0 } fg[ACTIVE] = { 0.0, 0.0, 0.0 } } widget "*ScrolledWindow*" style "scrollbar" widget "*plugin_scrwin*" style "plugin_scrwin" widget "*TreeView*" style "view" widget "*TextView*" style "view" widget "*List*" style "view" widget "*Notebook*" style "button" widget "*Scrollbar*" style "scrollbar" widget "*Separator*" style "scrollbar" widget "*Progress*" style "progressbar" widget "*OptionMenu*" style "button" widget "*Menu*" style "menu" widget "*SpinButton*" style "spin_button" widget "*Scale*" style "scale" widget "*AqualungLoopBar*" style "loop_bar" widget "*Button*" style "button" widget "*GtkEntry*" style "entry" widget "*Combo*" style "combo_box" widget "*nostyle" style "nostyle" # --- checkbutton widget "*check_on_window" style "window" widget "*check_on_notebook" style "button" # --- main window style "viewport" { bg[NORMAL] = { 0.3, 0.2, 0.0 } } style "time_viewport" = "viewport" { bg_pixmap[NORMAL] = "time_bg.png" } style "title_viewport" = "viewport" { bg_pixmap[NORMAL] = "pine.png" } style "info_viewport" = "title_viewport" { } style "big_timer_label" { fg[NORMAL] = { 0.6 , 1.0, 1.0 } font_name = "Courier 19" } style "small_timer_label" { fg[NORMAL] = { 0.0, 1.0, 1.0 } font_name = "Courier 11" } style "label_title" { fg[NORMAL] = { 0.9, 0.9, 1.0 } font_name = "Sans Bold 12" } style "label_info" { fg[NORMAL] = { 1.0, 1.0, 0.9 } font_name = "Sans 8" } style "scale_pos" = "scale" { GtkScale::slider-length = 31 } style "scale_vol" = "scale" { GtkScale::slider-length = 11 } style "scale_bal" = "scale" { GtkScale::slider-length = 11 } widget "*time_viewport" style "time_viewport" widget "*title_viewport" style "title_viewport" widget "*info_viewport" style "info_viewport" widget "*big_timer_label" style "big_timer_label" widget "*small_timer_label" style "small_timer_label" widget "*label_title" style "label_title" widget "*label_info" style "label_info" widget "*scale_pos" style "scale_pos" widget "*scale_vol" style "scale_vol" widget "*scale_bal" style "scale_bal" # --- music store style "music_tree" = "view" { fg[NORMAL] = { 0.0, 0.0, 1.0 } font_name = "Lucida 12" } style "comment_view" = "view" { font_name = "Lucida 10" } widget "*music_tree" style "music_tree" widget "*comment_view" style "comment_view" # --- playlist style "play_list" = "view" { fg[NORMAL] = { 0.0, 0.0, 1.0 } fg[SELECTED] = { 1.0, 0.0, 0.0 } fg[INSENSITIVE] = { 0.0, 0.0, 0.0 } font_name = "Lucida 12" } style "playlist_color" { fg[NORMAL] = { 0.0, 0.0, 0.0 } fg[ACTIVE] = { 0.0, 0.0, 0.0 } fg[SELECTED] = { 1.0, 0.0, 0.0 } fg[INSENSITIVE] = { 0.0, 0.0, 0.0 } } style "playlist_tab_close_button" = "button" { bg_pixmap[NORMAL] = "" bg_pixmap[PRELIGHT] = "" bg_pixmap[ACTIVE] = "" bg[PRELIGHT] = { 0.75, 0.23, 0.27 } bg[ACTIVE] = { 0.45, 0.15, 0.15 } } style "playlist_tab_label" { font_name = "Sans 10" } widget "*play_list" style "play_list" widget "*playlist_color_indicator*" style "playlist_color" widget "*playlist_tab_label*" style "playlist_tab_label" widget "*playlist_tab_close_button*" style "playlist_tab_close_button" # --- plugins style "plugin_name" { font_name = "Lucida Bold 14" } style "plugin_maker" { font_name = "Lucida Bold 12" } style "plugin_bypass_button" = "button" { bg_pixmap[ACTIVE] = "" bg[ACTIVE] = { 1.0, 0.0, 0.0 } fg[NORMAL] = { 1.0, 1.0, 1.0 } fg[PRELIGHT] = { 1.0, 1.0, 1.0 } fg[ACTIVE] = { 1.0, 1.0, 1.0 } } style "plugin_scale" = "scale" { bg_pixmap[ACTIVE] = "" bg[ACTIVE] = { 0.8, 0.83, 0.9 } } style "plugin_toggled" = "button" { bg_pixmap[ACTIVE] = "" bg[ACTIVE] = { 0.7, 0.6, 0.6 } } widget "*plugin_name" style "plugin_name" widget "*plugin_maker" style "plugin_maker" widget "*plugin_bypass_button*" style "plugin_bypass_button" widget "*plugin_scale" style "plugin_scale" widget "*plugin_toggled" style "plugin_toggled" # --- mod info list style "samples_instruments_list" { font_name = "Monospace 10" } widget "*samples_instruments_list" style "samples_instruments_list" aqualung-0.9beta11/skin/woody/next.png0000644000175000001440000000031710612341733014704 00000000000000PNG  IHDR PLTE 333w5jtRNS@fbKGDH pHYs  tIME  8z<\5휉4 {*99ĥuc\ۓdDZ#H,b؂TZj00_0 *B(Wp"J?<7I#jMy]u#MO d&hRHAlh:A,|Jz!oRL(ڿ׍Lh+T' Fe#Cram^3+.H#+q9\6RH0SFPe'yYbuE,Zu}_ދX9ɡnMSUU}os.ЍYVmSGqU7bH6E2L'[(<{R؏/צ7c!oKr$5ZƟ$)IiT7k!궗{TFkBRyݴZVD%d2rۮ"-E5MH٠bبGOkS󃰯]( "˒YLkeXAEKViۛf ӣWb[ %(SNZ=ԯ,^7CFy'7-t?)~gli` In f{}נr$IĹ~}0\3}]jk(.yNUqR ]Хƪdo[ [yͳ|62\*'ՏmN:th;lс 7iGj*/mҹM%.Fh^irZddPra5!tăvoP*_؛<Ǫn^\6$2!u 9{e?stL%s!$ =[9m?ZmvԷ 21i:SfIq&΋u 6_a)=kd/8`@lSg{vM;E#3kOcF-B&sRi]s!O/&YU7ݸjXYPxX(X .)ձ8IfGQqU5]ޜ2K%M˥JR QkWY&pF4A>>܎?dnuPWD=Ra^5aTY~t8ྺ:bi4Ih:!IZi@3 e{ xKU1 ŤJXct:Y⫈ .kp1;XܮQkA f)< jIy̰_5IHWWﱵaHuG I~yZhm,YI$otjhFÔ˯* 3(ޣIM7.tKQ]G0([ھ6׀A .p c1Ճ?a,3K.Qw]O'.d \PwCkճc,×[`lKdoچ=l`U#VKy"ٗXIPAϠ{ ^x6H@0*F|JQ0p~l 0jЇi.0H X= FW C Hɼ%,rkfG ku.菩Hڸ(-5;Ǩ8SF& !!ThV YblptVP#c4X3ɓI V>HAO{7k +@B"h]ߒ '&ta~.^bծ"G @o:0{VB bB;dg/d9R*|l*$ M g: S]qX_]!Z Scq<2Q˷wʠg;vlp|"`md; }Vg'YCqQ.2]204[G& 9;AUJ/JVI#\W NgӰDxoYah8E/ ε$<l f$R+M(gE}J N,&/-#oA 0!B,,?y)a``POG4`$qښg0O< g)}/Rnq'+p"g yRw.%Yd1'<1a=Og}|iTo>V,^N2}i gK~A+?S]Wk,-f#RFM^b7umvy.c/&ݘ<@:9?stJh@pTe!4{s֩W0MXt8PR(5ZV^sDAJ(JMyZ$rڈ7ϢG%UYɃ+{7fI)$xG(M*-@X(>J| sT*y{@c>Eɂkx-۫ Qɖ] XbJIo$!4o]^!''O3ӆ.0_y. %t C?$;Dȼ5jm =XyU& n~bQ8U۾zվ*>70N([3*Cu` 8M uAlwƀPT.ص^&t7Rs2;|ӶMGVL v`R8NcSZLV{9/˺HL:#9 -)6'ӿ_='@8 ¡'͆#s "\1iyH9 %i؄I+RgER>D U գd?΁^P҄%E|'Vs M:3A UX01;5]HI﹃z9y gI,ݮ_y~G-VZ(ufr-T[%J%'64NOA{%Lp+.Z~q8b{k[S?Ie8ـYCUOG,}pG1$Fa{CȇEwˉ6(l?T H.XN)CM L OXE/5*rÑ>nh.deCI-xxALSpHV$}Q#\??^c\P]QB#rb'a6oMpØFp0ݰbFTI0喸72^auUP_27>Wu1'̮[~ShbYUp#0)b _ y-έ!龼ȵKli͹cFk-yVqQ޽˻x76[VX5 Nu@+5v' ~]3y}zYFX9IO̥PZC?vʝ7\Ea"DXl-ؙ٭a\_gz.%N[L'a@k)3<% 2=V/ \q9$[(`Wή>~< 8EB0ԇwîGpɂe8wLpW؏~qk9.P#̚fU}4:Za{q-v VUH?LCeǝ+K-%t1]E*v?# *!W+ "!IH+y/BB݀PWu 3T2,8R6]SUo0_c* "\NI .~Jrn{ ӈgxL+6-8@/&)%@S fV,dpp1z8m#%+V\,? O\,JɳҼR2? R'J_N1LhtFէ/™kxytҚR(hL(.їi1M%<ּZՕ`z P/hD?ULO ;MY$e8"(~܍沷 #0?? \MF䶷 %›f8V:9>Y\yJ8 Kϴ+g6scczRL8_%;<+ E]8x }Whڬ{u۳1iKXw^_2[䥈~E LbCX?drs;\&6MQB[ HXd֠^ٛ^8&O Ia#mlv #z1\Q?>Ep G?o1gH%Ե" ՝".N8{"w^ak+Mv&[qjlf @4 'a^P̾B`RݝBm]Nؗ{p]9aTs0+Ah)/{͍KޝY$")VLBgB`|U8}r]a,Yn*Bj,f_sPd|pr hF?{Z NXܞKƿDpoȑu޿5~ƽ rFq)7IENDB`aqualung-0.9beta11/skin/woody/wood2.png0000644000175000001440000000641010612341733014760 00000000000000PNG  IHDR22)xPLTEF'G'L&H(J)I)N(O)L+K+M+T(Q*S+N-R+W*T,O.S,U-Y+P/T-V.Z,Q0U.W.R1V/ T1X/W/ ].a,\.U2Y0^/b-]/[1V3Z1_0c.^0[2\3`1d/_1a1\3]4e0`2 ^4b2Y6]4c3g1f1a3!_5c3^5 d4h2_5!l0g2`6d4i3m1f5h3j3a7e5o2n2g6i4k4b8f6j4 h7l5p3c9g7q4l5 n6i8v2m6q4h8 j8r5m6!o7s5w3n7r5i9!k9f;!j9"p8t6x4o8l:t6m;z5q9u7y5p9m;u7r:z6|6q:w8n<{6x9s;p=}7t;5x9o= s; |7y:v<q>~8u<y:z;w=r?9v=z;~9{<x>:s@w>{<;9y?}=;x?<:z@~><>?z@ ={A;=?@>|B<>@=?}CA=A>@~DB@B?CAEC@BFDBCAG?EACFDFBCEAGCHDFBHDEGEFJIGKIJHKIJMKLMMN?bKGDH pHYs  tIME  (c IDATHVLSMsN1ĨӇ\QN_R~.P.J%]w 5[˥6BXmY/}k\DQ(tV&MN珼'|@AU]& v5Bdw:^L\P_WlVbFeƶjh7$[Zq9j TR*9DcV+r֕-\[$E尬CTR%sUu&G}>B}VÄcjU lD(*X!U44J2hd|F+i%@-2κe{7n~VV]&WPLBYpSXc"qn"zbXߕɁn`( :(+ xa6A êjZe/wggct^bD[@* 핕{%%JV)[CT LHtJqct2q'vm|>69TXՆ78Z 9Pdsb $٣oG$"8?iY޻᱙fgfBW.^8N P턦JJ>+1=RzП;޼~8=`'EK/~m "N'z~W'm+_~|V Q J"9`ЩFweXI5HJXĎ C򢂼>?ZK,-)*.۾-RQfoMՅ.@C;:qnA'#K&~`< Ƃ}쉾dܝP V(i6OD%_qqNgBȍ8CNoSu AyK流hl3p:/6^cxǴaҕKe[dޢ4*DXaZsX$C' 4rZ8Fmᴗ < #!Wc2s`3nq0n rЅPxp4 $"@Sf`8 ?<<8 3cv:;~[Ip+`_MJ M jF`Fi?f!E?хB+sr܈N_FnxfWoޤ=K$ h|bxy:{jzj:foc:ϣ_>}0W.dAOݿsGF&dz2#Tj|K\lŋljj~nng_Bw7sz{/ 3?Pjn\t¥[= ??zoe27oLkj|^6“A B0:M.<{Ov'$9B06;9m_?k.GuaF"paXf`0P jn ť2(+y صh(xvyptn'T1;#t*`왰?p&&:;4u{zZV@xKdB`ErB9:7'F+4 F"4E8a34f;^F*-˕#c ט ̦_D֮BbAooB'$c" &ڢCXSX {]LV;;N1rNh z]Dk2 h18y':/I?`?qIH$|'CǻAvMLCv(,Z]XTOٳXQ? '/./<~~Sz,V,ݢeXn4&#nx >?6Aq=iGPZ/o-<}}8vur<&Zxџ/^`Ǜu)(~3m-^!1KW/d$s;-ZW(,:A}=}DJ2 }E9}ׯ^ v5˖;J1] i&pDjPyBu@-;7NfLΜ(('P\ijVܰQ/7T*6 r!:ˆĿ`FV(4b\la^B$jq-4p_GO$}=1.`ȓp )*FF=p="A*iw(kڎf!NFJ"L&2)XP"Uwj***bqЭ@@ )m@wKc ˑ \K${6~µ ?-)mMdMvF`qfD"0b Wڰ9Z Q!h[ *(aAn{% 8<̙?etXOَۛe 2yC1H~*|IENDB`aqualung-0.9beta11/skin/woody/wood3.png0000644000175000001440000001562710612341733014773 00000000000000PNG  IHDR``F tPLTE~WzW~^W~^^f^^f^ff^ffmmfffmmmfmmuffmmuufmmuummuuu|mmuu||muu|||muuu|||uu||u|||||||||ȨȫȫȫȯȯȯȳȳȷϳȷȷȺϷϺyܱbKGDH pHYs  tIME   ϰIDATh%zܶ%MJIܘuI;0M9A aCSx ^pr}]EfH{{eRK3/xCEmvP?՛ᦩmghꪪ^ڜ tyuQ E<'ҴM&{"'9O%+qXHے|:̰IF2hn4Ǿ.|i)Z%Gf;;^l8)њ}-b4-( )V7Q@fe=ܶ+HKQMR6!X?6S >`HdӚY0VlRZ6: dSUBW,t!庮*Y@5V4JI xw{=%qt``ZQƶƤ *jtidA Q(!WV%*%)Tiּf7x~[gyWz+&< !lߺLH]C^1u}O΅j S\IEϗxyN~׏yw%y׿[*{:l(wLΔizR+4"qn|RcJKmߴB :Pqs^sc @d8 Y|~/l7;;Q߾9U rJ7OCZIZ(iA)I|H=/i6圔@q"TJ:!B(RVխ_]u@0 AhUF1"+(%v@S,ɽ?yN?NYUѕCva4~TI`h &Oټ$ip<_T$ji8fhLys}5֖syQ?7e^g lȀmlo^ڮ bhd}Mi3琊jy)W7n Rݓ~hhN{O6r=XUjO bW.ba^쯍RϨNuX.iX.UQ؏<:\dd73v'S,w3p% ;n zKKIB+>a͜dv=q4P` QXL tI56O85,h?X5*18MIiUKczhIBeֆap; aR(+'lNh%·fIJKtBN'y:ܫ) S",(&,`Ϡ~x:&60?-uGtSojnl\5p|7lVJ\.Ic{Gwj.xr8qL'S] hp~]d0K*2g!bNyPQ+k\+͸T㸬$g%= ܰv9j'!IxC'G'I"hr:+q09ĄEH(f TTR-j\5t+2w1딌Ec@Z^ o @;Y*fR@L2LJq<#5l:.Y!`t`2@Yeb`17dCÈ* p;вc$J.Ҵ(C IE"/s$gkN@?S a*2A7pYFa.X(;\lA, B֑Zcq /6B8?jN@_NDc1n!{GRWY5^ش.DK$QD>xRj-Y=[^Z%_2X(c=*dJdN;0kO#B=LTb1wP- T1%|-<lMU>{_ %0;(1AK2@-l5N\ؾ9lZ Ȭ<0c4F51IP%/1hX$"͒̌N#cjZ@'#è}Yb+ F[fE+ 5n7CI0,L`"Qj2`aКZ0xm2^2* Ul>'ƖRI.8Xݏѻ%kL7ot?znp8#QkZ(:*%,ڇ RZU+d bDYA3zKc5~bB$O&I3t[< U>SvެO&9 wM|K: ЙZ9"xiTFD(RfX~i^VgX9lv 1O IKb)w0tgϓ9Hb+470'L! gua}uja<7NpȨwG<,m(bP~0رi9QS\,9[f @G8vO~$CÀ?Ztq4U)(EXU$A@3_n38I\WL ^e lk), :ג85LKD4X)[8ߗ?Zp,у ; PDDڇE=C=!рDZkkO{ϟT}'IRRxL@ІZzm`H;q6-Nu]ծ)Ҭ4fbJ#5xYn[׵۝=epCL`tc )Buh D.yR~[p4/$Sӯ`pQj@4fdQ~H& сof{%E9KWio5MRTIHQ"'TZ1T._/7Q|,lNu165Tf !h}^=(T#ZWh5-4HBifBNN4|g ]`:$IU]K~Hw:y)jqzhLh2 YŢp}}]guy}n`QVhA'Tj_1pꦃ\kLR!#n17ez$%mpǦ s^uU u2DSGsZRl 7O`{O8 ,5p=C5-N#D˛ G""E b<'r9+Pu V ϊ}@iG~* K,u~9Oά#ǐ E"z-,'ڔ񋋣WWD_ a"ʮL^A\eLD\#>`*q0ezx;\JF2m``eI&h3%"A`!n;< 5rW4+ '{׷k2).avXB˷ϪI!S2͓Glqn q兕E}t_:`KMoDZlγPr/f !(/pJ~Mnn}-Z?:z}eVNs֐s~e8??>?rg>;|pQ"0/3w=nO-D0}x@͵|ĔSقXg8ro蝇G+gW?ks`L"! |NL/îGpɂU8wLpW؏~qk8.P#̚fU}4:Za{q-v VUH?LCeǝ+K-%t1]E*v?# *!W+ "!IH+y/BB݀PWu 3T2,8R6]SUo0_c* "\NI .~Jrn{ ӈgxL+6+8@/&)%@3 fV,dpp1z8m#%+VL,? O\,JӽҼ M32? R'J_N1LhtFէ/™kxytҚR(hL(.їY1͔%<μZՕ`z P/hD?ULO;MY$e8"(~܍沷 #L0??f \MF䶷 %›f<V:9>Y\yJ8 Kϴ+g6scczRL8_%;<+ E]8x }Whڬ{u۳1iKXw^_2[䥈~E LbCX?drs;\&6MQB[ HXd֠^ٛ^8& Ia#mlv #z1\Q?>Ep G?m1H%Ե" ՝".Nf8{"w^ak+Mv&[qjlf @4 'a^P̾B`RݝBm]Nؗ{p]o8aUs0+Ch/{͍˰ޝYͲ$"VLCgB`|U8}Mr]a,Yn&Bj,f^sPd|pr hF?{Z NXܞKʿDpoȑu޿3~ֽ rFnF>TIENDB`aqualung-0.9beta11/skin/woody/wood4.png0000644000175000001440000001562510612341733014772 00000000000000PNG  IHDR``F tPLTEzeHtiHziNzlHzlNiNzlUzoNlNlUoNoUlUoNrUoUr[o[uUrUoUu[r[o[uUu[r[uaxUuUx[u[xauaxUx[|[xa|ax[|[~axa|a~[|g~a|[~g|a~m~[|g~aa~gg|g[~aaa~gggmaaggmmaggmmgggmmmtggmmttgmmttgmmmttzmtmttzzmttzztzztzzzzz̠bKGDH pHYs  tIME  3w{ IDATh%z6%֎Ԗ[I&#K`ڠ8<ΰ۫y]n'w>xK]ǖH{{`eRKS/xCEmvP?՛ᦩmghꪪ^ڜ tyuQg E<'ҴM&{"'9%+qXHے|:IͰ'IJRhn4Ǿ.|i)Z%Gf;;^l8)њ}-b4-( )V7Q@fe=ܶ+HKQMR6!X?6S +.qe,5` "AߥyT Muvs3+NXͭ)'ƞ^dUo|uE·!<W:{˟y3Z64X0$@7ykP9N$K\9ŏI}K}Ѿv q|xltIu^<@8)X؏Ui Cu]cUփ-lk.@ ]͍6B'l:{|K4 6ƣm5ITն\ȦPB4E49JT2J2T 9y0n:A(jVMcU7|o/y.`Cuf2b} 9:@-_piJƍA ?㻠{ i^jPaQL12EL4K'/Ӧrzd@t}+D>-B&sRi]s!O/&YU7ݸjXYPxX(X .)ձ8IfӇQQU5]ޜ2K%MɥJR QkWY&pF4A>>܎?dnuPWDݟRa^5aTY~t8ྺ:bi4Ih:!׿}'΁fʠWޗT5bIa. tW\bv]^kA f)< jIy̰߯5IHWW0 Nc$l`:ZP e$ͼ QD6t, T~u\$U7:x@X{54aR]WńفQx$ |b} QSm knv]AI0%|{|L}aZ /]O'.d \PwCkճc,×[`lޤMdoچl`U#VKy"ٗXIPAϠ{ ^ ʡӤ%>2 KWiiАU7]LM d$?Kv%(\8x QlhYf4 fb L$J [,ZS [ V+\!_EdRU9e q3zףd醵 nT g$jm\kcT?Q#Ze@_R4Xj1U8Pt[:+(wF@1|IsW _L$iaуʧsx=ݛ5C gx!4CoɆ:S0G??jhrţA T=K +n!rI!t]S3Ɨay2)>^l6q3)a̿,8^U-)α8t(ۻ eP ;6M8>g062t>p3V_׸(S. qݏdrB -B& 9;AUJ/JVI#\ N'ӰDxoYah8E/ ε$<l f$ӯV"P ,܃-UA YL?Zp,у ; PDDڇE=C=!рDZkkO{ϟT}IRRxL@ІZzm`H;q6-Nu]ծ)4fbJ#5xYn[׵۝=epCL`tc )Buh D.yR}[p4/$SӯapQj@4fdQ~H& сof{%u,=wڛxMU`#RH&Y U ,Kx p>ۅS]̹| *Y=@x1Zբ~dA5D U գd?΁^P҄%E|'Vs M>3A UdĂ9ݹBZLz%ԣρS8sMbv mq+jXi) yRRo(:rȂ8=͖0 /[GՍX 5:I*: |=b!;Gd!1 D>x/Z[L/XN)Gџ` <_@aE]7"4*2MS9$[/_G|TFa0DveH3J(ʒT!%ѦJEpBݾwJyj hZMN07odR\x‚.zQqs%Ds!+oOmãbb_G%/cGw&Q xP; xXm4kd'eGMqNj =Pn{#IPWu(8{sU}71o/U[==B)e'9Џ +\+R;-69qjme8*>j@q{?_.fs-|+@,k':+DL?]ݮ [>~x|}$MՏ#'R(R! g?9wk;[qvv|vv[}~.0"E-ؙ٭a\_gz.%N[L'a@k)3<% 2=V/ \Oq9$;(`Wή>~< 8EB0ԇ_]#*pp᮰W!>簻@\2kU] 0>h‡ǭر,+XU!Y#3Lwv,|x`,gDH BVw=qX\*$"'$!Y @wjZ@C\-TxSʔ$KtMU|$0| pe8%'%T)1q1XL#&{1E ۴H[P:`f2O9B/Yn;jAITxx+Ù7ǔ_3zFlZ}sQL*4< wp-[(%RKn9תf4K''nNםb6[mW茪OO_3|5P>bQ<+i1M%DvUNO@@'aWΫnR3+GYͯ\t8+y}%.{ 79xQiw>^v F6svl"F w*(4ݮk#䄫+zy)"_ч(ٿW&w~~1V}*"5WW*N),)Sĺp|G#Hn@ۭÈv k&66@ϛ+hRI8u퇈AECbui} !pAʇ4V!{\8.9C3?h‰FXTwP[WDlN{"c=J*gt^sRwcV4|u9)5wN_3o@5 y@tKo\Bz"ZQEhVB!'o=Q۾r$f_u©GC_.z\IENDB`aqualung-0.9beta11/skin/woody/wood5.png0000644000175000001440000002120310612341733014760 00000000000000PNG  IHDR``F PLTEQVUU#[& a&]+\.`-c*i,c0a3c/l.i0h2o0o.a7c6i2i7h6o3i7l7i9o5u4n7s8u7h=o:o<n8!i?u9s=n<u;o@sB{>u>; z@tB oD{?uC{AuBuD? {AvA'zE@{CtG{F{C"sJC {HGGuKCE!{H"zJHzG3{J"LFJLML"KKM{RyTP|R!P!MRN-OO!T T!|W!R TPO-MWQ!Q9V![!VS-X \S9V-ZS3W"Z'V]'[ U#Z_ V-X"a'\(_\ ` \3b%e'^ Y0](\ `)c-c _(c-]'_ a4g*d'`'`0d&]#c.h.\%j&d&a+m-i&l,k&f3f)m3h)f,e%k'l/d2r0n/v3j-r7k%m+g(i2r0p3e#l/j)t0z9w8d)t3h1l*q0o(u+w3x+o#r*s7u'8p&r1x'z0x*v#r'~1u):w&6|.~19v"7-y-)7}"„+61094‹+ӄ&+5Њ%Ŏ.4Տ*ř.%8ɞ6՛*Ǣ1Ԥ1ɯ6ZèbKGDH pHYs  tIME  "[!IDAThzq|n^ۄ]IeVUlb"+ %8%ոtDu:2L# " !E<-r%s), ,=Gw۽UG,}<;c*t08=]47MO700pvtn#,$Nq"Ĩ]lݶqQ9hCt Mh 6趹ˆAƘOjCpXR#0G9xdl}IP.g!hyLy n]H\!VNڿW 4^cc\b0*FA0Ra!67lKD@I$,tBX ӽ~0}x:@8IlE*˼$A%iTUdU8I:{xĂ@IŜDt-)I38ĤaW}pX/OM'Irm(O&cRL`eN  GG'/kUV MiPO8ۼ~Ð+5W/=Po!s#QU_"<;.A2DMU % IA!_raNd16G0aýnBTERtC״ v۞C492Yì.dL 5HcDB_&y3LyEcK;,rB&bbF@0nI1:MfGt4IBTq+cCG҅˗//K|>Ca uA-f~o3BPqun65X]JezRT˚j*e>Ή0B8| w;jDE A!0z^6SC)( BP85#)GB!I8nl0f΄ØK%Jf `O|Ҁ<%h!D0TR!T1f[@>봷=ȣJ%8mO?N(dUJ@{{@rEKǓzDT>e-QPp'X尷m "d ,\ C!El 凄%"=N5+ofc.Ylr3ζ͏9!FL=?Dp B dH Ip Q˪Vz` duoVucIH㜖­# G}S! ͘(@@D HQU1JF2(&k81H8i$&bBmm.P[z?nNjà!tlɪo*l|Azb&㋥RseBp5-wnFȜㅀ@Q 8"T*(zj.w񭜦efkןut<ώW+ҝlڜV-si X^&1*BLbH%)V9hIj aL;(FLҌZ~L%QIkWdlxƁa|{y \Nh(+BQ`BL&X$b,7fZ`I1欘dZ :d i&-NLiZ=Pb'3 8 ^ ?B≷8,dGV2ydAO1zDdV+FcZv@n{}74bn]7 wm!GDk}(}]8Wgg#Τ̵k*FMFU"/K^P1XzR: Hm:_ŵ+Zm^7K5#MC7#~ٵ.Ϟ= #WET,ͦ%Ɛfz@!aqҒ"8AVHOˍR{Y(ŏu*%kW+VF}BdD`mP?NIGFɴ̬U2̺UOVZ \Q_4!OȧecgeVV*YV~P55i+'@LhA7wabYWܪFӲ̣˳?~?O~T)isW,3}TQ+eFIi:.+X."*uOr&~Lsf:Jy1=2K:VͫՍU# CLHT\n8 1BS0șҝj9ÐxA!Mkiٜ/ԑqq"=0iȖ-t1Bk:(c |WЈP yAF9o5/oC!}bjڂσb`CLbLo QD0< B4A}#[ȑ[%X$K}iyܙ g׏^ZY_ɇ//G[+IMǗo5=f UVM,,E}~!w5ѕ; z&pjw9^< 䯬?Xޘ_?sFOe˺ܼ?w_Pm^pe|̏zKu-W0揦YZzma`u/]X\lez^X|{͕Çwo߻~6g.z 22 c~(qqE}y#'&;E"rtg+^j޽Bgg/W.})uK/R4k‚3kUb|,2sִ[}ۿ~݇Ho_wo\ ܣ=S5oY&$?q28r0ּ( z跖3 HѨi?{~?}ӻ=y޽M^dkOaJuC/7|Ԕve4t+۟WVn>xp~^ziֺEݱ`giopP/[_o^Y+fkܙyR j kk0OWV~?ArVp|agwoז3ԥK^8[j9e0baۋY"SI=bZ55f?Yכ7ol4wWΤm¤f4FzBfmTizHca[d9 I\.WA Zh }~F}eeѨ_pi}ݳ"꺄b]hIFqoXl.WH&B73Fj-_msJY3RݿqjjFjj-f$m\ݨuǸHd|~UI`'}` RDNc5w/Wi޽~`z~߾K=gS%+S1Z9)j+\d2҇$EůU6rjͯjŤ!;ٍ,B.޺ԯpm,4&4'S,G.6K9-#gEF ݬ㪘C/@oOu@O޼ j . HNfcǂkI*mT5`1EA VU PGePbIfTTv1,B%IUXb29c\X./-mlnP2\}MyYBV5UB!)K)9M ;ӅrA}DL Y2FʤR OjV\(r ( q8.`f!E;wn}fyI;,?XxsF+#FFɪTd㉭ߥ:zǍgNӛhU )$r9"<<0m$ 4tg[G۱cGk^xUqOMPHJ $ r6oG#(G<L\Z-cMAA~Qaқdetf2_o|\y{R9'mA6՘HR您ÎX1D/qptnGA7_xV' L4/ :~#iu!f2һwJj42b\L0޷弄,C!@`.KpFD9G{h{Nչw˅YkgD n&Qnv|kNw`n1opw=ǒix\aXWZ,%}ؗv~5ں1~Y 8%Hv{PD=Ey<~2 ";im "ƁZwb8d-7=jiQ!?-jɂP[g7GP˪Knk9E<66콴S_ܟ?%EHڨ)Z UNҌ4hm0 (`6$&ޭ o=~Q,W2eV.\XX)mm]X/j.76b0~{4@2#PDBI}'_{Q<Ǔ L ?snJ}T2 DLgg՚yqydY!Muԙ&Q3?ͭ[s=;t"x}B<Ma,Q_ny!*JAbEYuGCãekӂsG@ξ-mO=xjK{J/K4νIYvؾbz;Le FA I;^K=>0?tle*o߲N'?@ ~!P݃i{;`;Uj\zc#Aш*cİbʅJv!732ID8[r`梟`l 0i /xf""@ckwtXsE` uk5.Gv BIV]QP:B`vb;bIIaC f Hz8<M+ZBRHNi{m]('s*b8M7r<  c`#q!?':]P-ù$ ` HZBͼq A0Ҷ ^egIENDB`aqualung-0.9beta11/skin/woody/wood6.png0000644000175000001440000001562710612341733014776 00000000000000PNG  IHDR``F tPLTEĨĨĪĭĭĭıııijij˱ij˱˳ķ˳ķ˳ķķ˷ĺ˷ѳĺ˷˺Ľ˺ѷĽ˺ѷ˺˽Ѻ˽Ѻ˽Ѻѽѽѽß׽æ׽ßæìßƦæƬìƟɦƦæɬƬƲɦƦ̬ɬƬɲƲɦ̬ɬ̲ɲ̬ϲ̲Ϭϲ̲ϸϲӲӲ$bKGDH pHYs  tIME  Ls[IDATh%zܶ%MJ;IuI;ILX!(x \x ^p|}EfH{{eRK3\6RH0SFPe'yYbuE4Zu}_ދX9ɡnMSUU}os.ЍiZmSGqV7bH6E2L'[(<}R؏/צ7c!oKr$3ZƟ$hT7k!궗{TFkBRyݴZVD%d2pۮ"-E5MH٠bبGOkS󃰯]( "MYLkeXAEKViۛf ӣWb[ &(SNZ=ԯ,^7CJy'7-t?)~gli` In f{}נr$IĹ~}0\S}]jk(.yNUqR ]Хƪdo[ [y|62\*'ՏmN:th;lс 7iGj*/mҹM%.Fh^irZdPra5!tăvoP*_؛<Ǫn^\6$2!u 9L{e?stL%s!$ =[9m?ZmvԷ 21i:SIq&΋u 6_a)=kd/8`@lSf{vM;E#SkOcF-B&sRY]s!O/&iU7ݸjXYPxX(X .)ձ8ɤfGQqU5]ޜ2K%˥J2 gQkWY&pF4A>>܎?dnuPWD=Ra^5aTY~t8ྺ:bi4Ih:!IVi@3 e{ xKU1 ŤJXct:Y⫈ .kp1;XܮQkA fg)< )jIy̰_5IHWWLﱵaHuG I~yZhm,YI$otjhJÔ˯* 3(ޣIM7.tKQ]G)0([ھ6׀A .p c1Ճ?a,3K.Qw]O'.d \PwCkճcL,ŗ[`ldKdoچ=l`U#VKy"ٗXIPAϠ{ ^ITdr0Tg fZ[%Yp,D)oP?je `%7y䰐p 8G֎x6H@0*F~JQ0p~l 0jЇi.0H X= FW C Hɼ%,rkfG ku.菩Hڸ(-5;Ǩ83FJ & !!ThV YblptVP#c,X3ɓI V>HAO{7k +@B"h]ߒ'&ta~.^bծ"G@o:0{VB bB;gdg/d9R*|l*$ M g: S]qX_]!Z Scq<2Q˷wJg;vlp|"`md; }Vg'YCqQ.2]204]G& 9;AUJ/JVI#\W NgӰDxoYah8E / ε$<l f$R+M(gE}J N,&/-#oA 0!B,,?y)a``POG4`$qښg0O< g)}/Rnq'+p"ͧ yRw.%Ydd1'<1a=Og}|iTo>V,^N2}i gK~A+?S]Wk4+f#RFM^b7umvy.c/&ݘ<@:9?stJh@pT!4{s֩W0MXt8PR(5ZV^sDAJ(JMyZ$rڈ7ϢG%UY+{7I)$xG(M*-@X(>J| sT*y{@c>Eɂkx-۫ Qɖ] XbIIo$!4o]^!''O3ӆ.0_y. %t C?$;Dȼ5jm =XyU& n~bQ8U۾zվ*>70N([S*CuҘ` 8M uAtwƀPT.ص^&t7Rs2=|ӶMGVL v`R8NcSZLV{9/˺JH̆:e#9 -)6'ӿ_='@8 ¡'͆#s "\1iyH9 %i؄I+RgER>D U գd?΁^P҄%E|'Vs M:3A UX01;5]HI﹃z9y gI,ݮ_y~G-VZ(ufr-T[%J%'64NA{%Lp+.Z~q8b{k[S?d8ـYCUOG,}pG1$Fa{CȇEwˉ6e(l?L H.XN)C L OXE/5*rÑ>nh.deCI-xxALSpHV$}Q#\??^c\P]QB#rb'a6oMpØFp0ݰbdFTI0喸72^auUP_27>Wu1'̮[~ShbYUp#0)b _ y-έ!پȵKli͹cFk-yVqQ޽˻x76[VX5 Nu@+5v' ~]3y}zYFX9IO̥PZC?vʝ7\Ea"DXl-ؙ٭a\_gz.%N[L'a@k)3<% 2=V/ \q9$[(`Wή>~< 8EB0ԇwîGpɂe8wLpW؏~qk9.P#̚fU}4:Za{q-v VUH?LCeǝ+K-%t1]E*v?# *!W+ "!IH+y/BB݀PWu 3T2,8R6]SUo0_c* "\NI .~Jrn{ ӈgxL+6+8@/&)%@3 fV,dpp1z8m#%+V\,? O\,JӽҼM32? R'J_N1LhtFէ/™kxytҚR(hL(.їY1͔%<ּZՕ`z P/hD?ULO;MY$e8"(~܍沷 #L0??f \MF䶷 %›f<V:9>Y\yJ8 Kϴ+g6scczRL8_%;<+ E]8x }Whڬ{u۳1iKXw^_2[䥈~E LbCX?drs;\&6MQB[ HXd֠^ٛ^8& Ia#mlv #z1\Q?>Ep G?o1gH%Ե" ՝".Nf8{"w^ak+Mv&[qjlf @4 'a^P̾B`RݝBm]Nؗ{p]9aTs0+Ah/{͍˰ޝYͲ$"VLBgB`|U8}Mr]a,Yn&Bj,f_sPd|pr hF?{Z NXܞKʿDpoȑu޿5~ƽ rFwWIENDB`aqualung-0.9beta11/skin/no_skin/0000777000175000001440000000000011331334362013601 500000000000000aqualung-0.9beta11/skin/no_skin/Makefile.am0000644000175000001440000000012410715346600015551 00000000000000skindir = $(pkgdatadir)/skin/no_skin skin_DATA = rc *.png EXTRA_DIST = $(skin_DATA) aqualung-0.9beta11/skin/no_skin/Makefile.in0000644000175000001440000002250011331334252015557 00000000000000# Makefile.in generated by automake 1.10.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # This Makefile.in 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. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = skin/no_skin DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = SOURCES = DIST_SOURCES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; am__installdirs = "$(DESTDIR)$(skindir)" skinDATA_INSTALL = $(INSTALL_DATA) DATA = $(skin_DATA) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBAVCODEC_CFLAGS = @LIBAVCODEC_CFLAGS@ LIBAVCODEC_LIBS = @LIBAVCODEC_LIBS@ LIBAVFORMAT_CFLAGS = @LIBAVFORMAT_CFLAGS@ LIBAVFORMAT_LIBS = @LIBAVFORMAT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ var = @var@ skindir = $(pkgdatadir)/skin/no_skin skin_DATA = rc *.png EXTRA_DIST = $(skin_DATA) all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu skin/no_skin/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu skin/no_skin/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh install-skinDATA: $(skin_DATA) @$(NORMAL_INSTALL) test -z "$(skindir)" || $(MKDIR_P) "$(DESTDIR)$(skindir)" @list='$(skin_DATA)'; for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ f=$(am__strip_dir) \ echo " $(skinDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(skindir)/$$f'"; \ $(skinDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(skindir)/$$f"; \ done uninstall-skinDATA: @$(NORMAL_UNINSTALL) @list='$(skin_DATA)'; for p in $$list; do \ f=$(am__strip_dir) \ echo " rm -f '$(DESTDIR)$(skindir)/$$f'"; \ rm -f "$(DESTDIR)$(skindir)/$$f"; \ done tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(DATA) installdirs: for dir in "$(DESTDIR)$(skindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-skinDATA install-dvi: install-dvi-am install-exec-am: install-html: install-html-am install-info: install-info-am install-man: install-pdf: install-pdf-am install-ps: install-ps-am installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-skinDATA .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic distclean \ distclean-generic distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-skinDATA install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic pdf pdf-am ps ps-am uninstall \ uninstall-am uninstall-skinDATA # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: aqualung-0.9beta11/skin/no_skin/rc0000644000175000001440000001042510657267102014055 00000000000000 style "window" { bg_pixmap[NORMAL] = "" bg_pixmap[PRELIGHT] = "" bg_pixmap[ACTIVE] = "" } style "main_window" = "window" { } style "plugin_scrwin" = "window" { bg_pixmap[NORMAL] = "" } widget "*GtkWindow*" style "window" widget "*Dialog*" style "window" widget "*FileSelection*" style "window" widget "*playlist_window*" style "window" widget "*main_window" style "main_window" style "button" { bg_pixmap[NORMAL] = "" bg_pixmap[PRELIGHT] = "" bg_pixmap[ACTIVE] = "" } style "view" { } style "scrollbar" { bg_pixmap[NORMAL] = "" bg_pixmap[PRELIGHT] = "" bg_pixmap[ACTIVE] = "" } style "progressbar" { } style "notebook" { } style "entry" = "view" { } style "combo_box" { } style "menu" = "button" { } style "spin_button" = "button" { } style "scale" { bg_pixmap[NORMAL] = "" bg_pixmap[PRELIGHT] = "" bg_pixmap[ACTIVE] = "" } style "loop_bar" { bg_pixmap[NORMAL] = "" } style "checkbutton" { bg_pixmap[NORMAL] = "" bg_pixmap[PRELIGHT] = "" bg_pixmap[ACTIVE] = "" } style "nostyle" { bg_pixmap[NORMAL] = "" bg_pixmap[PRELIGHT] = "" bg_pixmap[ACTIVE] = "" } widget "*ScrolledWindow*" style "scrollbar" widget "*plugin_scrwin*" style "plugin_scrwin" widget "*TreeView*" style "view" widget "*TextView*" style "view" widget "*List*" style "view" widget "*Notebook*" style "notebook" widget "*Scrollbar*" style "scrollbar" widget "*Separator*" style "scrollbar" widget "*Progress*" style "progressbar" widget "*OptionMenu*" style "button" widget "*Menu*" style "menu" widget "*SpinButton*" style "spin_button" widget "*Scale*" style "scale" widget "*AqualungLoopBar*" style "loop_bar" widget "*Button*" style "button" widget "*GtkEntry*" style "entry" widget "*Combo*" style "combo_box" widget "*CheckButton*" style "checkbutton" widget "*nostyle" style "nostyle" widget "*check_on_window" style "window" widget "*check_on_notebook" style "notebook" style "viewport" { bg_pixmap[NORMAL] = "" } style "time_viewport" = "viewport" { bg_pixmap[NORMAL] = "" } style "title_viewport" = "viewport" { bg_pixmap[NORMAL] = "" } style "info_viewport" = "title_viewport" { } style "big_timer_label" { } style "small_timer_label" { } style "label_title" { } style "label_info" { } style "scale_pos" = "scale" { GtkScale::slider-length = 31 } style "scale_vol" = "scale_pos" { GtkScale::slider-length = 11 } style "scale_bal" = "scale_pos" { GtkScale::slider-length = 11 } widget "*time_viewport" style "time_viewport" widget "*title_viewport" style "title_viewport" widget "*info_viewport" style "info_viewport" widget "*big_timer_label" style "big_timer_label" widget "*small_timer_label" style "small_timer_label" widget "*label_title" style "label_title" widget "*label_info" style "label_info" widget "*scale_pos" style "scale_pos" widget "*scale_vol" style "scale_vol" widget "*scale_bal" style "scale_bal" style "music_tree" = "view" { } style "comment_view" = "view" { } widget "*music_tree" style "music_tree" widget "*comment_view" style "comment_view" style "play_list" = "view" { } style "playlist_color" { } style "playlist_tab_close_button" = "button" { bg_pixmap[NORMAL] = "" bg_pixmap[PRELIGHT] = "" bg_pixmap[ACTIVE] = "" } style "playlist_tab_label" { } widget "*play_list" style "play_list" widget "*playlist_color_indicator*" style "playlist_color" widget "*playlist_tab_label*" style "playlist_tab_label" widget "*playlist_tab_close_button*" style "playlist_tab_close_button" style "plugin_name" { } style "plugin_maker" { } style "plugin_bypass_button" = "button" { bg_pixmap[ACTIVE] = "" } style "plugin_scale" = "scale" { bg_pixmap[ACTIVE] = "" } style "plugin_toggled" = "button" { bg_pixmap[NORMAL] = "" bg_pixmap[PRELIGHT] = "" bg_pixmap[ACTIVE] = "" } widget "*plugin_name" style "plugin_name" widget "*plugin_maker" style "plugin_maker" widget "*plugin_bypass_button*" style "plugin_bypass_button" widget "*plugin_scale" style "plugin_scale" widget "*plugin_toggled" style "plugin_toggled" style "samples_instruments_list" { } widget "*samples_instruments_list" style "samples_instruments_list" aqualung-0.9beta11/skin/no_skin/next.png0000644000175000001440000000062410657267102015212 00000000000000PNG  IHDR7bKGD̿ pHYs  tIME %!upL tEXtCommentMenu-sized icon ========== (c) 2003 Jakub 'jimmac' Steiner, http://jimmac.musichall.cz created with the GIMP, http://www.gimp.orggGIDAT(c` Y~qY4 _[!B^ C&_J0,A "]>%LcS„`wu`V< b3{Tsl pICf``a``@ASp YJy&ZQIENDB`aqualung-0.9beta11/skin/no_skin/pause.png0000644000175000001440000000052410657267102015350 00000000000000PNG  IHDR7bKGD̿ pHYs  tIME %( tEXtCommentMenu-sized icon ========== (c) 2003 Jakub 'jimmac' Steiner, http://jimmac.musichall.cz created with the GIMP, http://www.gimp.orggGMIDAT(c` X4 _[ٔ9RP5^ !d6D B-aX7 WCF$*G$(IENDB`aqualung-0.9beta11/skin/no_skin/play_pause.png0000644000175000001440000000063511062755225016377 00000000000000PNG  IHDR7gAMA abKGD̿ pHYs  tIME 7>rtEXtCommentMenu-sized icon ========== (c) 2003 Jakub 'jimmac' Steiner, http://jimmac.musichall.cz created with the GIMP, http://www.gimp.orggGIDAT(c` X _sج~Tgbf*a \T%L-AS„i#&l._ S„s]VGA!FF ^AX0cັ*%$!NC[)Q,M_@IENDB`aqualung-0.9beta11/skin/no_skin/play.png0000644000175000001440000000055610657267102015205 00000000000000PNG  IHDR7bKGD̿ pHYs  tIME %{tEXtCommentMenu-sized icon ========== (c) 2003 Jakub 'jimmac' Steiner, http://jimmac.musichall.cz created with the GIMP, http://www.gimp.orggGgIDAT(c` *W&dίJP, % "mJ0ex2g`dĩ4 t nbt#i8't84RIENDB`aqualung-0.9beta11/skin/no_skin/prev.png0000644000175000001440000000064310657267102015211 00000000000000PNG  IHDR7bKGD̿ pHYs  tIME %AtEXtCommentMenu-sized icon ========== (c) 2003 Jakub 'jimmac' Steiner, http://jimmac.musichall.cz created with the GIMP, http://www.gimp.orggGIDAT(c` X4 _[aRl3c`````b#!<&33`6_ ,&l:S΄_6EȖJA֍%WXGs؟J89{q*HB*$h@h_<yA HIIENDB`aqualung-0.9beta11/skin/no_skin/repeat_all.png0000644000175000001440000000026510657267102016345 00000000000000PNG  IHDR 2 HbKGDop pHYs  tIME "kBIDAT(c``aaPg``OE1 *I.e"F5++9'`i, rÐ*$'n ,IENDB`aqualung-0.9beta11/skin/no_skin/repeat.png0000644000175000001440000000030410657267102015507 00000000000000PNG  IHDR 2 HbKGDop pHYs  tIME !,oQIDAT(c``aaPg``OE1*I.OtqVV ,j6E0!b4!nC$ަ$+N>IENDB`aqualung-0.9beta11/skin/no_skin/shuffle.png0000644000175000001440000000036210657267102015667 00000000000000PNG  IHDRrP6bKGDop pHYs  tIME 0(IDAT8c`  100'3`1|wPS& ըi+!yG@fLIjXkeyJgćVQ1Œv)YW:Û٣)C =E#¶IENDB`aqualung-0.9beta11/skin/no_skin/stop.png0000644000175000001440000000054610657267102015224 00000000000000PNG  IHDRabKGD pHYs  tIME #7^tEXtCommentMenu-sized icon ========== (c) 2003 Jakub 'jimmac' Steiner, http://jimmac.musichall.cz created with the GIMP, http://www.gimp.orggG[IDAT8c`02000022Jw^z100'?L/ AK,!肘>a0j0j)As4-8ǑIENDB`aqualung-0.9beta11/src/0000777000175000001440000000000011331334363011765 500000000000000aqualung-0.9beta11/src/Makefile.am0000644000175000001440000000214211134430741013732 00000000000000SUBDIRS = decoder encoder img po bin_PROGRAMS = aqualung aqualung_SOURCES = \ about.h about.c \ build_store.h build_store.c \ common.h \ cdda.h cdda.c \ cddb_lookup.h cddb_lookup.c \ cd_ripper.h cd_ripper.c \ core.h core.c \ cover.h cover.c \ export.h export.c \ ext_title_format.h ext_title_format.c \ file_info.h file_info.c \ gui_main.h gui_main.c \ httpc.h httpc.c \ i18n.h \ ifp_device.h ifp_device.c \ loop_bar.h loop_bar.c \ metadata.h metadata.c \ metadata_api.h metadata_api.c \ metadata_ape.h metadata_ape.c \ metadata_flac.h metadata_flac.c \ metadata_id3v1.h metadata_id3v1.c \ metadata_id3v2.h metadata_id3v2.c \ metadata_ogg.h metadata_ogg.c \ music_browser.h music_browser.c \ options.h options.c \ playlist.h playlist.c \ plugin.h plugin.c \ podcast.h podcast.c \ ports.h ports.c \ rb.h rb.c \ search.h search.c \ search_playlist.h search_playlist.c \ segv.h segv.c \ skin.h skin.c \ store_cdda.h store_cdda.c \ store_file.h store_file.c \ store_podcast.h store_podcast.c \ transceiver.c transceiver.h \ trashlist.c trashlist.h \ utils.c utils.h \ utils_gui.c utils_gui.h \ version.h \ volume.c volume.h aqualung-0.9beta11/src/Makefile.in0000644000175000001440000005216211331334253013752 00000000000000# Makefile.in generated by automake 1.10.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # This Makefile.in 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. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : bin_PROGRAMS = aqualung$(EXEEXT) subdir = src DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = am__installdirs = "$(DESTDIR)$(bindir)" binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) PROGRAMS = $(bin_PROGRAMS) am_aqualung_OBJECTS = about.$(OBJEXT) build_store.$(OBJEXT) \ cdda.$(OBJEXT) cddb_lookup.$(OBJEXT) cd_ripper.$(OBJEXT) \ core.$(OBJEXT) cover.$(OBJEXT) export.$(OBJEXT) \ ext_title_format.$(OBJEXT) file_info.$(OBJEXT) \ gui_main.$(OBJEXT) httpc.$(OBJEXT) ifp_device.$(OBJEXT) \ loop_bar.$(OBJEXT) metadata.$(OBJEXT) metadata_api.$(OBJEXT) \ metadata_ape.$(OBJEXT) metadata_flac.$(OBJEXT) \ metadata_id3v1.$(OBJEXT) metadata_id3v2.$(OBJEXT) \ metadata_ogg.$(OBJEXT) music_browser.$(OBJEXT) \ options.$(OBJEXT) playlist.$(OBJEXT) plugin.$(OBJEXT) \ podcast.$(OBJEXT) ports.$(OBJEXT) rb.$(OBJEXT) \ search.$(OBJEXT) search_playlist.$(OBJEXT) segv.$(OBJEXT) \ skin.$(OBJEXT) store_cdda.$(OBJEXT) store_file.$(OBJEXT) \ store_podcast.$(OBJEXT) transceiver.$(OBJEXT) \ trashlist.$(OBJEXT) utils.$(OBJEXT) utils_gui.$(OBJEXT) \ volume.$(OBJEXT) aqualung_OBJECTS = $(am_aqualung_OBJECTS) aqualung_LDADD = $(LDADD) DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(aqualung_SOURCES) DIST_SOURCES = $(aqualung_SOURCES) RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ install-html-recursive install-info-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBAVCODEC_CFLAGS = @LIBAVCODEC_CFLAGS@ LIBAVCODEC_LIBS = @LIBAVCODEC_LIBS@ LIBAVFORMAT_CFLAGS = @LIBAVFORMAT_CFLAGS@ LIBAVFORMAT_LIBS = @LIBAVFORMAT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ var = @var@ SUBDIRS = decoder encoder img po aqualung_SOURCES = \ about.h about.c \ build_store.h build_store.c \ common.h \ cdda.h cdda.c \ cddb_lookup.h cddb_lookup.c \ cd_ripper.h cd_ripper.c \ core.h core.c \ cover.h cover.c \ export.h export.c \ ext_title_format.h ext_title_format.c \ file_info.h file_info.c \ gui_main.h gui_main.c \ httpc.h httpc.c \ i18n.h \ ifp_device.h ifp_device.c \ loop_bar.h loop_bar.c \ metadata.h metadata.c \ metadata_api.h metadata_api.c \ metadata_ape.h metadata_ape.c \ metadata_flac.h metadata_flac.c \ metadata_id3v1.h metadata_id3v1.c \ metadata_id3v2.h metadata_id3v2.c \ metadata_ogg.h metadata_ogg.c \ music_browser.h music_browser.c \ options.h options.c \ playlist.h playlist.c \ plugin.h plugin.c \ podcast.h podcast.c \ ports.h ports.c \ rb.h rb.c \ search.h search.c \ search_playlist.h search_playlist.c \ segv.h segv.c \ skin.h skin.c \ store_cdda.h store_cdda.c \ store_file.h store_file.c \ store_podcast.h store_podcast.c \ transceiver.c transceiver.h \ trashlist.c trashlist.h \ utils.c utils.h \ utils_gui.c utils_gui.h \ version.h \ volume.c volume.h all: all-recursive .SUFFIXES: .SUFFIXES: .c .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" @list='$(bin_PROGRAMS)'; for p in $$list; do \ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ if test -f $$p \ ; then \ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \ $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \ else :; fi; \ done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; for p in $$list; do \ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \ rm -f "$(DESTDIR)$(bindir)/$$f"; \ done clean-binPROGRAMS: -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) aqualung$(EXEEXT): $(aqualung_OBJECTS) $(aqualung_DEPENDENCIES) @rm -f aqualung$(EXEEXT) $(LINK) $(aqualung_OBJECTS) $(aqualung_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/about.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/build_store.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cd_ripper.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cdda.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cddb_lookup.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/core.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cover.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/export.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext_title_format.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file_info.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gui_main.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/httpc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ifp_device.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/loop_bar.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/metadata.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/metadata_ape.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/metadata_api.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/metadata_flac.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/metadata_id3v1.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/metadata_id3v2.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/metadata_ogg.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/music_browser.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/options.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/playlist.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/podcast.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ports.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rb.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/search.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/search_playlist.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/segv.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/skin.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/store_cdda.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/store_file.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/store_podcast.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/transceiver.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trashlist.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utils_gui.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/volume.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ distdir=`$(am__cd) $(distdir) && pwd`; \ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ (cd $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$top_distdir" \ distdir="$$distdir/$$subdir" \ am__remove_distdir=: \ am__skip_length_check=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile $(PROGRAMS) installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-binPROGRAMS clean-generic mostlyclean-am distclean: distclean-recursive -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-exec-am: install-binPROGRAMS install-html: install-html-recursive install-info: install-info-recursive install-man: install-pdf: install-pdf-recursive install-ps: install-ps-recursive installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-binPROGRAMS .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \ install-strip .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am check check-am clean clean-binPROGRAMS \ clean-generic ctags ctags-recursive distclean \ distclean-compile distclean-generic distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-binPROGRAMS install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \ ps ps-am tags tags-recursive uninstall uninstall-am \ uninstall-binPROGRAMS # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: aqualung-0.9beta11/src/about.h0000644000175000001440000000175710612341733013176 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: about.h 524 2007-01-06 15:39:18Z pasp $ */ #ifndef _ABOUT_H #define _ABOUT_H void create_about_window(void); #endif /* _ABOUT_H */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/about.c0000644000175000001440000005524611331325773013200 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: about.c 1110 2010-01-31 12:24:58Z peterszilagyi $ */ #include #include #include #include "common.h" #include "version.h" #include "i18n.h" #include "about.h" GtkWidget * about_window; extern GtkWidget * main_window; static gint ok(GtkWidget * widget, gpointer data) { gtk_widget_destroy(about_window); return TRUE; } gint about_key_pressed(GtkWidget * widget, GdkEventKey * event, gpointer * data) { switch (event->keyval) { case GDK_q: case GDK_Q: case GDK_Escape: ok(NULL, NULL); return TRUE; }; return FALSE; } void create_about_window() { GtkWidget * vbox0; GtkWidget * vbox; GtkWidget * xpm; GdkPixbuf * pixbuf; GtkWidget * frame; GtkWidget * scrolled_win; GtkWidget * view; GtkTextBuffer * buffer; GtkTextIter iter; GtkWidget * hbuttonbox; GtkWidget * ok_btn; GdkColor white = { 0, 49152, 51118, 52429 }; GdkColor blue1 = { 0, 41288, 47841, 55050 }; GdkColor blue2 = { 0, 45288, 51841, 60050 }; GdkColor blue3 = { 0, 55552, 56832, 57600}; GtkTextTag * tag; GtkTextTag * tag2; char path[MAXLEN]; about_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_transient_for(GTK_WINDOW(about_window), GTK_WINDOW(main_window)); gtk_window_set_modal(GTK_WINDOW(about_window), TRUE); gtk_widget_set_name(about_window, ""); gtk_window_set_title(GTK_WINDOW(about_window), _("About")); gtk_widget_set_size_request(about_window, 483, 430); gtk_window_set_position(GTK_WINDOW(about_window), GTK_WIN_POS_CENTER); gtk_widget_modify_bg(about_window, GTK_STATE_NORMAL, &white); g_signal_connect(G_OBJECT(about_window), "key_press_event", G_CALLBACK(about_key_pressed), NULL); vbox0 = gtk_vbox_new(FALSE, 0); gtk_container_add(GTK_CONTAINER(about_window), vbox0); vbox = gtk_vbox_new(FALSE, 0); gtk_container_set_border_width(GTK_CONTAINER(vbox), 5); gtk_box_pack_end(GTK_BOX(vbox0), vbox, TRUE, TRUE, 0); hbuttonbox = gtk_hbutton_box_new(); gtk_widget_set_name(hbuttonbox, ""); gtk_box_pack_end(GTK_BOX(vbox), hbuttonbox, FALSE, TRUE, 0); gtk_button_box_set_layout(GTK_BUTTON_BOX(hbuttonbox), GTK_BUTTONBOX_END); ok_btn = gtk_button_new_from_stock (GTK_STOCK_CLOSE); gtk_widget_set_name(ok_btn, ""); g_signal_connect(ok_btn, "clicked", G_CALLBACK(ok), NULL); gtk_container_add(GTK_CONTAINER(hbuttonbox), ok_btn); gtk_widget_modify_bg(ok_btn, GTK_STATE_NORMAL, &blue1); gtk_widget_modify_bg(ok_btn, GTK_STATE_PRELIGHT, &blue2); gtk_widget_modify_bg(ok_btn, GTK_STATE_ACTIVE, &blue2); frame = gtk_frame_new(NULL); gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN); scrolled_win = gtk_scrolled_window_new(NULL, NULL); gtk_widget_set_name(scrolled_win, ""); gtk_widget_set_name(GTK_SCROLLED_WINDOW(scrolled_win)->vscrollbar, ""); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_win), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); gtk_widget_modify_bg(GTK_SCROLLED_WINDOW(scrolled_win)->vscrollbar, GTK_STATE_NORMAL, &blue1); gtk_widget_modify_bg(GTK_SCROLLED_WINDOW(scrolled_win)->vscrollbar, GTK_STATE_PRELIGHT, &blue2); gtk_widget_modify_bg(GTK_SCROLLED_WINDOW(scrolled_win)->vscrollbar, GTK_STATE_ACTIVE, &blue3); gtk_widget_modify_bg(GTK_SCROLLED_WINDOW(scrolled_win)->vscrollbar, GTK_STATE_INSENSITIVE, &blue2); view = gtk_text_view_new(); gtk_widget_set_name(view, ""); gtk_widget_modify_base(view, GTK_STATE_NORMAL, &blue3); gtk_text_view_set_left_margin(GTK_TEXT_VIEW(view), 3); gtk_text_view_set_right_margin(GTK_TEXT_VIEW(view), 3); gtk_text_view_set_editable(GTK_TEXT_VIEW(view), FALSE); gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(view), FALSE); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(view), GTK_WRAP_WORD); buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view)); gtk_text_view_set_buffer(GTK_TEXT_VIEW(view), buffer); tag = gtk_text_buffer_create_tag(buffer, NULL, "foreground", "#0000C0", NULL); tag2 = gtk_text_buffer_create_tag(buffer, NULL, "family", "monospace", NULL); /* insert text */ gtk_text_buffer_get_end_iter(buffer, &iter); gtk_text_buffer_insert_with_tags(buffer, &iter, _("Build version: "), -1, tag, NULL); gtk_text_buffer_insert_at_cursor(buffer, AQUALUNG_VERSION, -1); gtk_text_buffer_insert_at_cursor(buffer, "\n\n", -1); gtk_text_buffer_get_end_iter(buffer, &iter); gtk_text_buffer_insert_with_tags(buffer, &iter, _("Homepage:"), -1, tag, NULL); gtk_text_buffer_insert_at_cursor(buffer, " http://aqualung.factorial.hu\n", -1); gtk_text_buffer_insert_at_cursor(buffer, "\nCopyright (C) 2004-2010 Tom Szilagyi\n\n\n", -1); gtk_text_buffer_get_end_iter(buffer, &iter); gtk_text_buffer_insert_with_tags(buffer, &iter, _("Authors:"), -1, tag, NULL); gtk_text_buffer_insert_at_cursor(buffer, "\n\n", -1); gtk_text_buffer_insert_at_cursor(buffer, _("Core design, engineering & programming:\n"), -1); gtk_text_buffer_insert_at_cursor(buffer, "\tTom Szilagyi \n\n", -1); gtk_text_buffer_insert_at_cursor(buffer, _("Skin support, look & feel, GUI hacks:\n"), -1); gtk_text_buffer_insert_at_cursor(buffer, "\tPeter Szilagyi \n\n", -1); gtk_text_buffer_insert_at_cursor(buffer, _("Programming, GUI engineering:\n"), -1); gtk_text_buffer_insert_at_cursor(buffer, "\tTomasz Maka \n\n", -1); gtk_text_buffer_insert_at_cursor(buffer, _("OpenBSD compatibility, metadata tweaks:\n"), -1); gtk_text_buffer_insert_at_cursor(buffer, "\tJeremy Evans \n\n\n", -1); gtk_text_buffer_get_end_iter(buffer, &iter); gtk_text_buffer_insert_with_tags(buffer, &iter, _("Translators:"), -1, tag, NULL); gtk_text_buffer_insert_at_cursor(buffer, "\n\n", -1); gtk_text_buffer_insert_at_cursor(buffer, _("French:\n"), -1); gtk_text_buffer_insert_at_cursor(buffer, "\tJulien Lavergne \n", -1); gtk_text_buffer_insert_at_cursor(buffer, "\tLouis Opter \n\n", -1); gtk_text_buffer_insert_at_cursor(buffer, _("German:\n"), -1); gtk_text_buffer_insert_at_cursor(buffer, "\tWolfgang St\303\266ggl \n\n", -1); gtk_text_buffer_insert_at_cursor(buffer, _("Hungarian:\n"), -1); gtk_text_buffer_insert_at_cursor(buffer, "\tPeter Szilagyi \n\n", -1); gtk_text_buffer_insert_at_cursor(buffer, _("Italian:\n"), -1); gtk_text_buffer_insert_at_cursor(buffer, "\tMichele Petrecca \n\n", -1); gtk_text_buffer_insert_at_cursor(buffer, _("Japanese:\n"), -1); gtk_text_buffer_insert_at_cursor(buffer, "\tNorihiro Yoneda \n\n", -1); gtk_text_buffer_insert_at_cursor(buffer, _("Russian:\n"), -1); gtk_text_buffer_insert_at_cursor(buffer, "\tAlexander Ilyashov \n", -1); gtk_text_buffer_insert_at_cursor(buffer, "\tVladimir Smolyar \n\n", -1); gtk_text_buffer_insert_at_cursor(buffer, _("Swedish:\n"), -1); gtk_text_buffer_insert_at_cursor(buffer, "\tNiklas 'Nixon' Grahn \n\n", -1); gtk_text_buffer_insert_at_cursor(buffer, _("Ukrainian:\n"), -1); gtk_text_buffer_insert_at_cursor(buffer, "\tSergiy Niskorodov \n", -1); gtk_text_buffer_insert_at_cursor(buffer, "\tVladimir Smolyar \n\n\n", -1); gtk_text_buffer_get_end_iter(buffer, &iter); gtk_text_buffer_insert_with_tags(buffer, &iter, _("Graphics:"), -1, tag, NULL); gtk_text_buffer_insert_at_cursor(buffer, "\n\n", -1); gtk_text_buffer_insert_at_cursor(buffer, _("Logo, icons:\n"), -1); gtk_text_buffer_insert_at_cursor(buffer, "\tMaja Kocon \n\n\n", -1); gtk_text_buffer_get_end_iter(buffer, &iter); gtk_text_buffer_insert_with_tags(buffer, &iter, _("This Aqualung binary is compiled with:"), -1, tag, NULL); gtk_text_buffer_insert_at_cursor(buffer, "\n\n\t", -1); gtk_text_buffer_insert_at_cursor(buffer, _("Optional features:"), -1); gtk_text_buffer_insert_at_cursor(buffer, "\n", -1); gtk_text_buffer_insert_at_cursor(buffer, "\t\t[", -1); gtk_text_buffer_get_end_iter(buffer, &iter); #ifdef HAVE_LADSPA gtk_text_buffer_insert_with_tags(buffer, &iter, "+", -1, tag2, NULL); #else gtk_text_buffer_insert_with_tags(buffer, &iter, " ", -1, tag2, NULL); #endif /* HAVE_LADSPA */ gtk_text_buffer_insert_at_cursor(buffer, "]\t", -1); gtk_text_buffer_insert_at_cursor(buffer, _("LADSPA plugin support\n"), -1); gtk_text_buffer_insert_at_cursor(buffer, "\t\t[", -1); gtk_text_buffer_get_end_iter(buffer, &iter); #ifdef HAVE_CDDA gtk_text_buffer_insert_with_tags(buffer, &iter, "+", -1, tag2, NULL); #else gtk_text_buffer_insert_with_tags(buffer, &iter, " ", -1, tag2, NULL); #endif /* HAVE_CDDA */ gtk_text_buffer_insert_at_cursor(buffer, "]\t", -1); gtk_text_buffer_insert_at_cursor(buffer, _("CDDA (Audio CD) support\n"), -1); gtk_text_buffer_insert_at_cursor(buffer, "\t\t[", -1); gtk_text_buffer_get_end_iter(buffer, &iter); #ifdef HAVE_CDDB gtk_text_buffer_insert_with_tags(buffer, &iter, "+", -1, tag2, NULL); #else gtk_text_buffer_insert_with_tags(buffer, &iter, " ", -1, tag2, NULL); #endif /* HAVE_CDDB */ gtk_text_buffer_insert_at_cursor(buffer, "]\t", -1); gtk_text_buffer_insert_at_cursor(buffer, _("CDDB support\n"), -1); gtk_text_buffer_insert_at_cursor(buffer, "\t\t[", -1); gtk_text_buffer_get_end_iter(buffer, &iter); #ifdef HAVE_SRC gtk_text_buffer_insert_with_tags(buffer, &iter, "+", -1, tag2, NULL); #else gtk_text_buffer_insert_with_tags(buffer, &iter, " ", -1, tag2, NULL); #endif /* HAVE_SRC */ gtk_text_buffer_insert_at_cursor(buffer, "]\t", -1); gtk_text_buffer_insert_at_cursor(buffer, _("Sample Rate Converter support\n"), -1); gtk_text_buffer_insert_at_cursor(buffer, "\t\t[", -1); gtk_text_buffer_get_end_iter(buffer, &iter); #ifdef HAVE_IFP gtk_text_buffer_insert_with_tags(buffer, &iter, "+", -1, tag2, NULL); #else gtk_text_buffer_insert_with_tags(buffer, &iter, " ", -1, tag2, NULL); #endif /* HAVE_IFP */ gtk_text_buffer_insert_at_cursor(buffer, "]\t", -1); gtk_text_buffer_insert_at_cursor(buffer, _("iRiver iFP driver support\n"), -1); gtk_text_buffer_insert_at_cursor(buffer, "\t\t[", -1); gtk_text_buffer_get_end_iter(buffer, &iter); #ifdef HAVE_LOOP gtk_text_buffer_insert_with_tags(buffer, &iter, "+", -1, tag2, NULL); #else gtk_text_buffer_insert_with_tags(buffer, &iter, " ", -1, tag2, NULL); #endif /* HAVE_LOOP */ gtk_text_buffer_insert_at_cursor(buffer, "]\t", -1); gtk_text_buffer_insert_at_cursor(buffer, _("Loop playback support\n"), -1); gtk_text_buffer_insert_at_cursor(buffer, "\t\t[", -1); gtk_text_buffer_get_end_iter(buffer, &iter); #ifdef HAVE_SYSTRAY gtk_text_buffer_insert_with_tags(buffer, &iter, "+", -1, tag2, NULL); #else gtk_text_buffer_insert_with_tags(buffer, &iter, " ", -1, tag2, NULL); #endif /* HAVE_SYSTRAY */ gtk_text_buffer_insert_at_cursor(buffer, "]\t", -1); gtk_text_buffer_insert_at_cursor(buffer, _("Systray support\n"), -1); gtk_text_buffer_insert_at_cursor(buffer, "\t\t[", -1); gtk_text_buffer_get_end_iter(buffer, &iter); #ifdef HAVE_PODCAST gtk_text_buffer_insert_with_tags(buffer, &iter, "+", -1, tag2, NULL); #else gtk_text_buffer_insert_with_tags(buffer, &iter, " ", -1, tag2, NULL); #endif /* HAVE_PODCAST */ gtk_text_buffer_insert_at_cursor(buffer, "]\t", -1); gtk_text_buffer_insert_at_cursor(buffer, _("Podcast support\n"), -1); gtk_text_buffer_insert_at_cursor(buffer, "\t\t[", -1); gtk_text_buffer_get_end_iter(buffer, &iter); #ifdef HAVE_LUA gtk_text_buffer_insert_with_tags(buffer, &iter, "+", -1, tag2, NULL); #else gtk_text_buffer_insert_with_tags(buffer, &iter, " ", -1, tag2, NULL); #endif /* HAVE_LUA */ gtk_text_buffer_insert_at_cursor(buffer, "]\t", -1); gtk_text_buffer_insert_at_cursor(buffer, _("Lua (programmable title formatting) support\n"), -1); gtk_text_buffer_insert_at_cursor(buffer, "\n\t", -1); gtk_text_buffer_insert_at_cursor(buffer, _("Decoding support:"), -1); gtk_text_buffer_insert_at_cursor(buffer, "\n", -1); gtk_text_buffer_insert_at_cursor(buffer, "\t\t[", -1); gtk_text_buffer_get_end_iter(buffer, &iter); #ifdef HAVE_SNDFILE gtk_text_buffer_insert_with_tags(buffer, &iter, "+", -1, tag2, NULL); #else gtk_text_buffer_insert_with_tags(buffer, &iter, " ", -1, tag2, NULL); #endif /* HAVE_SNDFILE */ gtk_text_buffer_insert_at_cursor(buffer, "]\t", -1); gtk_text_buffer_insert_at_cursor(buffer, _("sndfile (WAV, AIFF, etc.)\n"), -1); gtk_text_buffer_insert_at_cursor(buffer, "\t\t[", -1); gtk_text_buffer_get_end_iter(buffer, &iter); #ifdef HAVE_FLAC gtk_text_buffer_insert_with_tags(buffer, &iter, "+", -1, tag2, NULL); #else gtk_text_buffer_insert_with_tags(buffer, &iter, " ", -1, tag2, NULL); #endif /* HAVE_FLAC */ gtk_text_buffer_insert_at_cursor(buffer, "]\t", -1); gtk_text_buffer_insert_at_cursor(buffer, _("Free Lossless Audio Codec (FLAC)\n"), -1); gtk_text_buffer_insert_at_cursor(buffer, "\t\t[", -1); gtk_text_buffer_get_end_iter(buffer, &iter); #ifdef HAVE_OGG_VORBIS gtk_text_buffer_insert_with_tags(buffer, &iter, "+", -1, tag2, NULL); #else gtk_text_buffer_insert_with_tags(buffer, &iter, " ", -1, tag2, NULL); #endif /* HAVE_OGG_VORBIS */ gtk_text_buffer_insert_at_cursor(buffer, "]\t", -1); gtk_text_buffer_insert_at_cursor(buffer, _("Ogg Vorbis\n"), -1); gtk_text_buffer_insert_at_cursor(buffer, "\t\t[", -1); gtk_text_buffer_get_end_iter(buffer, &iter); #ifdef HAVE_SPEEX gtk_text_buffer_insert_with_tags(buffer, &iter, "+", -1, tag2, NULL); #else gtk_text_buffer_insert_with_tags(buffer, &iter, " ", -1, tag2, NULL); #endif /* HAVE_SPEEX */ gtk_text_buffer_insert_at_cursor(buffer, "]\t", -1); gtk_text_buffer_insert_at_cursor(buffer, _("Ogg Speex\n"), -1); gtk_text_buffer_insert_at_cursor(buffer, "\t\t[", -1); gtk_text_buffer_get_end_iter(buffer, &iter); #ifdef HAVE_MPEG gtk_text_buffer_insert_with_tags(buffer, &iter, "+", -1, tag2, NULL); #else gtk_text_buffer_insert_with_tags(buffer, &iter, " ", -1, tag2, NULL); #endif /* HAVE_MPEG */ gtk_text_buffer_insert_at_cursor(buffer, "]\t", -1); gtk_text_buffer_insert_at_cursor(buffer, _("MPEG Audio (MPEG 1-2.5 Layer I-III)\n"), -1); gtk_text_buffer_insert_at_cursor(buffer, "\t\t[", -1); gtk_text_buffer_get_end_iter(buffer, &iter); #ifdef HAVE_MOD gtk_text_buffer_insert_with_tags(buffer, &iter, "+", -1, tag2, NULL); #else gtk_text_buffer_insert_with_tags(buffer, &iter, " ", -1, tag2, NULL); #endif /* HAVE_MOD */ gtk_text_buffer_insert_at_cursor(buffer, "]\t", -1); gtk_text_buffer_insert_at_cursor(buffer, _("MOD Audio (MOD, S3M, XM, IT, etc.)\n"), -1); gtk_text_buffer_insert_at_cursor(buffer, "\t\t[", -1); gtk_text_buffer_get_end_iter(buffer, &iter); #ifdef HAVE_MPC gtk_text_buffer_insert_with_tags(buffer, &iter, "+", -1, tag2, NULL); #else gtk_text_buffer_insert_with_tags(buffer, &iter, " ", -1, tag2, NULL); #endif /* HAVE_MPC */ gtk_text_buffer_insert_at_cursor(buffer, "]\t", -1); gtk_text_buffer_insert_at_cursor(buffer, _("Musepack\n"), -1); gtk_text_buffer_insert_at_cursor(buffer, "\t\t[", -1); gtk_text_buffer_get_end_iter(buffer, &iter); #ifdef HAVE_MAC gtk_text_buffer_insert_with_tags(buffer, &iter, "+", -1, tag2, NULL); #else gtk_text_buffer_insert_with_tags(buffer, &iter, " ", -1, tag2, NULL); #endif /* HAVE_MAC */ gtk_text_buffer_insert_at_cursor(buffer, "]\t", -1); gtk_text_buffer_insert_at_cursor(buffer, _("Monkey's Audio Codec\n"), -1); gtk_text_buffer_insert_at_cursor(buffer, "\t\t[", -1); gtk_text_buffer_get_end_iter(buffer, &iter); #ifdef HAVE_WAVPACK gtk_text_buffer_insert_with_tags(buffer, &iter, "+", -1, tag2, NULL); #else gtk_text_buffer_insert_with_tags(buffer, &iter, " ", -1, tag2, NULL); #endif /* HAVE_WAVPACK */ gtk_text_buffer_insert_at_cursor(buffer, "]\t", -1); gtk_text_buffer_insert_at_cursor(buffer, _("WavPack\n"), -1); gtk_text_buffer_insert_at_cursor(buffer, "\t\t[", -1); gtk_text_buffer_get_end_iter(buffer, &iter); #ifdef HAVE_LAVC gtk_text_buffer_insert_with_tags(buffer, &iter, "+", -1, tag2, NULL); #else gtk_text_buffer_insert_with_tags(buffer, &iter, " ", -1, tag2, NULL); #endif /* HAVE_LAVC */ gtk_text_buffer_insert_at_cursor(buffer, "]\t", -1); gtk_text_buffer_insert_at_cursor(buffer, _("LAVC (AC3, AAC, WavPack, WMA, etc.)\n"), -1); gtk_text_buffer_insert_at_cursor(buffer, "\n\t", -1); gtk_text_buffer_insert_at_cursor(buffer, _("Encoding support:"), -1); gtk_text_buffer_insert_at_cursor(buffer, "\n", -1); gtk_text_buffer_insert_at_cursor(buffer, "\t\t[", -1); gtk_text_buffer_get_end_iter(buffer, &iter); #ifdef HAVE_SNDFILE gtk_text_buffer_insert_with_tags(buffer, &iter, "+", -1, tag2, NULL); #else gtk_text_buffer_insert_with_tags(buffer, &iter, " ", -1, tag2, NULL); #endif /* HAVE_SNDFILE */ gtk_text_buffer_insert_at_cursor(buffer, "]\t", -1); gtk_text_buffer_insert_at_cursor(buffer, _("sndfile (WAV)\n"), -1); gtk_text_buffer_insert_at_cursor(buffer, "\t\t[", -1); gtk_text_buffer_get_end_iter(buffer, &iter); #ifdef HAVE_FLAC gtk_text_buffer_insert_with_tags(buffer, &iter, "+", -1, tag2, NULL); #else gtk_text_buffer_insert_with_tags(buffer, &iter, " ", -1, tag2, NULL); #endif /* HAVE_FLAC */ gtk_text_buffer_insert_at_cursor(buffer, "]\t", -1); gtk_text_buffer_insert_at_cursor(buffer, _("Free Lossless Audio Codec (FLAC)\n"), -1); gtk_text_buffer_insert_at_cursor(buffer, "\t\t[", -1); gtk_text_buffer_get_end_iter(buffer, &iter); #ifdef HAVE_VORBISENC gtk_text_buffer_insert_with_tags(buffer, &iter, "+", -1, tag2, NULL); #else gtk_text_buffer_insert_with_tags(buffer, &iter, " ", -1, tag2, NULL); #endif /* HAVE_VORBISENC */ gtk_text_buffer_insert_at_cursor(buffer, "]\t", -1); gtk_text_buffer_insert_at_cursor(buffer, _("Ogg Vorbis\n"), -1); gtk_text_buffer_insert_at_cursor(buffer, "\t\t[", -1); gtk_text_buffer_get_end_iter(buffer, &iter); #ifdef HAVE_LAME gtk_text_buffer_insert_with_tags(buffer, &iter, "+", -1, tag2, NULL); #else gtk_text_buffer_insert_with_tags(buffer, &iter, " ", -1, tag2, NULL); #endif /* HAVE_LAME */ gtk_text_buffer_insert_at_cursor(buffer, "]\t", -1); gtk_text_buffer_insert_at_cursor(buffer, _("LAME (MP3)\n"), -1); gtk_text_buffer_insert_at_cursor(buffer, "\n\t", -1); gtk_text_buffer_insert_at_cursor(buffer, _("Output driver support:"), -1); gtk_text_buffer_insert_at_cursor(buffer, "\n", -1); gtk_text_buffer_insert_at_cursor(buffer, "\t\t[", -1); gtk_text_buffer_get_end_iter(buffer, &iter); #ifdef HAVE_SNDIO gtk_text_buffer_insert_with_tags(buffer, &iter, "+", -1, tag2, NULL); #else gtk_text_buffer_insert_with_tags(buffer, &iter, " ", -1, tag2, NULL); #endif /* HAVE_SNDIO */ gtk_text_buffer_insert_at_cursor(buffer, "]\t", -1); gtk_text_buffer_insert_at_cursor(buffer, _("sndio Audio\n"), -1); gtk_text_buffer_insert_at_cursor(buffer, "\t\t[", -1); gtk_text_buffer_get_end_iter(buffer, &iter); #ifdef HAVE_OSS gtk_text_buffer_insert_with_tags(buffer, &iter, "+", -1, tag2, NULL); #else gtk_text_buffer_insert_with_tags(buffer, &iter, " ", -1, tag2, NULL); #endif /* HAVE_OSS */ gtk_text_buffer_insert_at_cursor(buffer, "]\t", -1); gtk_text_buffer_insert_at_cursor(buffer, _("OSS Audio\n"), -1); gtk_text_buffer_insert_at_cursor(buffer, "\t\t[", -1); gtk_text_buffer_get_end_iter(buffer, &iter); #ifdef HAVE_ALSA gtk_text_buffer_insert_with_tags(buffer, &iter, "+", -1, tag2, NULL); #else gtk_text_buffer_insert_with_tags(buffer, &iter, " ", -1, tag2, NULL); #endif /* HAVE_ALSA */ gtk_text_buffer_insert_at_cursor(buffer, "]\t", -1); gtk_text_buffer_insert_at_cursor(buffer, _("ALSA Audio\n"), -1); gtk_text_buffer_insert_at_cursor(buffer, "\t\t[", -1); gtk_text_buffer_get_end_iter(buffer, &iter); #ifdef HAVE_JACK gtk_text_buffer_insert_with_tags(buffer, &iter, "+", -1, tag2, NULL); #else gtk_text_buffer_insert_with_tags(buffer, &iter, " ", -1, tag2, NULL); #endif /* HAVE_JACK */ gtk_text_buffer_insert_at_cursor(buffer, "]\t", -1); gtk_text_buffer_insert_at_cursor(buffer, _("JACK Audio Server\n"), -1); gtk_text_buffer_insert_at_cursor(buffer, "\t\t[", -1); gtk_text_buffer_get_end_iter(buffer, &iter); #ifdef HAVE_PULSE gtk_text_buffer_insert_with_tags(buffer, &iter, "+", -1, tag2, NULL); #else gtk_text_buffer_insert_with_tags(buffer, &iter, " ", -1, tag2, NULL); #endif /* HAVE_PULSE */ gtk_text_buffer_insert_at_cursor(buffer, "]\t", -1); gtk_text_buffer_insert_at_cursor(buffer, _("PulseAudio\n"), -1); gtk_text_buffer_insert_at_cursor(buffer, "\t\t[", -1); gtk_text_buffer_get_end_iter(buffer, &iter); #ifdef _WIN32 gtk_text_buffer_insert_with_tags(buffer, &iter, "+", -1, tag2, NULL); #else gtk_text_buffer_insert_with_tags(buffer, &iter, " ", -1, tag2, NULL); #endif /* _WIN32 */ gtk_text_buffer_insert_at_cursor(buffer, "]\t", -1); gtk_text_buffer_insert_at_cursor(buffer, _("Win32 Sound API\n"), -1); gtk_text_buffer_insert_at_cursor(buffer, "\n\n", -1); gtk_text_buffer_insert_at_cursor(buffer, _("This program is free software; you can redistribute it and/or modify " "it under the terms of the GNU General Public License as published by " "the Free Software Foundation; either version 2 of the License, or " "(at your option) any later version.\n\n" "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.\n\n" "You should have received a copy of the GNU General Public License " "along with this program; if not, write to the Free Software " "Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA."), -1); gtk_text_buffer_get_iter_at_offset(buffer, &iter, 0); gtk_text_buffer_place_cursor(buffer, &iter); gtk_box_pack_end(GTK_BOX(vbox), frame, TRUE, TRUE, 6); gtk_container_add(GTK_CONTAINER(frame), scrolled_win); gtk_container_add(GTK_CONTAINER(scrolled_win), view); sprintf(path, "%s/logo.png", AQUALUNG_DATADIR); if ((pixbuf = gdk_pixbuf_new_from_file(path, NULL)) != NULL) { xpm = gtk_image_new_from_pixbuf (pixbuf); gtk_box_pack_start(GTK_BOX(vbox0), xpm, FALSE, FALSE, 0); gtk_widget_show(xpm); } gtk_widget_show_all(about_window); gtk_widget_grab_focus(ok_btn); } // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/build_store.h0000644000175000001440000000226210657140026014370 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: build_store.h 746 2007-07-30 15:24:09Z peterszilagyi $ */ #ifndef _BUILD_STORE_H #define _BUILD_STORE_H #include #include int build_is_busy(void); void build_store(GtkTreeIter * store_iter, char * file); xmlNodePtr build_store_get_xml_node(char * file); #endif /* _BUILD_STORE_H */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/build_store.c0000644000175000001440000026375511324131225014374 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: build_store.c 1092 2010-01-03 15:58:59Z peterszilagyi $ */ #include #include #include #include #include #include #include #include #include #include #include #include #ifdef _WIN32 #include #else #include #endif /* _WIN32*/ #include "common.h" #include "utils.h" #include "utils_gui.h" #include "decoder/file_decoder.h" #include "i18n.h" #include "options.h" #include "music_browser.h" #include "store_file.h" #include "metadata_api.h" #include "build_store.h" #include "cddb_lookup.h" extern options_t options; extern GtkTreeStore * music_store; extern GtkWidget * browser_window; extern GdkPixbuf * icon_artist; extern GdkPixbuf * icon_record; extern GdkPixbuf * icon_track; #ifdef HAVE_SNDFILE extern char * valid_extensions_sndfile[]; #endif /* HAVE_SNDFILE */ #ifdef HAVE_MPEG extern char * valid_extensions_mpeg[]; #endif /* HAVE_MPEG */ #ifdef HAVE_MOD extern char * valid_extensions_mod[]; #endif /* HAVE_MOD */ int build_busy; enum { BUILD_TYPE_STRICT, BUILD_TYPE_LOOSE, }; enum { SORT_NAME = 0, SORT_NAME_LOW, SORT_DIR, SORT_DIR_LOW, SORT_YEAR }; enum { CAP_ALL_WORDS = 0, CAP_FIRST_WORD }; enum { RECORD_NEW = 0, RECORD_EXISTS }; enum { DATA_SRC_CDDB = 0, DATA_SRC_META, DATA_SRC_FILE }; typedef struct _build_track_t { char filename[MAXLEN]; char d_name[MAXLEN]; char name[3][MAXLEN]; char final[MAXLEN]; char comment[MAXLEN]; float duration; float rva; int rva_found; struct _build_track_t * next; } build_track_t; typedef struct { char d_name[MAXLEN]; char dirname[MAXLEN]; char sort[MAXLEN]; char name[3][MAXLEN]; char final[MAXLEN]; char year[MAXLEN]; char comment[MAXLEN]; int unknown; } build_record_t; typedef struct { char d_name[MAXLEN]; char sort[MAXLEN]; char name[3][MAXLEN]; char final[MAXLEN]; int unknown; } build_artist_t; typedef struct { build_artist_t artist; build_record_t record; build_track_t * tracks; int flag; GtkTreeIter iter; } build_disc_t; typedef struct { int enabled[3]; int type[3]; int cddb_mask; } data_src_t; typedef struct { data_src_t * model; GtkListStore * list; } data_src_gui_t; typedef struct { int enabled; int pre_enabled; int low_enabled; int mode; char pattern[MAXLEN]; char ** pre_stringv; } capitalize_t; typedef struct { capitalize_t * model; GtkWidget * check; GtkWidget * combo; GtkWidget * check_pre; GtkWidget * entry_pre; GtkWidget * check_low; } capitalize_gui_t; typedef struct { char regexp[MAXLEN]; char replacement[MAXLEN]; regex_t compiled; int rm_number; int rm_extension; int us_to_space; int rm_multi_spaces; } file_transform_t; typedef struct { file_transform_t * model; GtkWidget * check_rm_number; GtkWidget * check_rm_extension; GtkWidget * check_us_to_space; GtkWidget * check_rm_multi_spaces; GtkWidget * entry_regexp; GtkWidget * entry_replacement; GtkWidget * label_error; } file_transform_gui_t; typedef struct { AQUALUNG_THREAD_DECLARE(thread_id); AQUALUNG_MUTEX_DECLARE(mutex); int type; int cancelled; int write_data_locked; data_src_t * data_src_artist; data_src_t * data_src_record; data_src_t * data_src_track; capitalize_t * capitalize_artist; capitalize_t * capitalize_record; capitalize_t * capitalize_track; file_transform_t * file_transform_artist; file_transform_t * file_transform_record; file_transform_t * file_transform_track; file_transform_t * file_transform_sandbox; file_transform_gui_t * snd_file_trans_gui; char * file; GtkTreeIter store_iter; GtkTreeIter artist_iter; int artist_iter_is_set; map_t * artist_name_map; char root[MAXLEN]; int artist_dir_depth; int reset_existing_data; int remove_dead_files; int artist_sort_by; int record_sort_by; int rec_add_year_to_comment; int trk_rva_enabled; int trk_comment_enabled; int excl_enabled; char excl_pattern[MAXLEN]; char ** excl_patternv; int incl_enabled; char incl_pattern[MAXLEN]; char ** incl_patternv; int cddb_enabled; int meta_enabled; GtkWidget * prog_window; GtkWidget * prog_cancel_button; GtkWidget * prog_file_entry; GtkWidget * prog_action_label; GtkWidget * snd_entry_input; GtkWidget * snd_entry_output; build_disc_t * disc; char action[MAXLEN]; char path[MAXLEN]; } build_store_t; void file_transform(char * buf, file_transform_t * model); data_src_t * data_src_new() { data_src_t * model; if ((model = (data_src_t *)malloc(sizeof(data_src_t))) == NULL) { fprintf(stderr, "build_store.c: data_src_new(): malloc error\n"); return NULL; } model->type[DATA_SRC_CDDB] = DATA_SRC_CDDB; model->type[DATA_SRC_META] = DATA_SRC_META; model->type[DATA_SRC_FILE] = DATA_SRC_FILE; #ifdef HAVE_CDDB model->enabled[0] = TRUE; model->cddb_mask = 1; #else model->enabled[0] = FALSE; model->cddb_mask = 0; #endif /* HAVE_CDDB */ model->enabled[1] = TRUE; model->enabled[2] = TRUE; return model; } void data_src_save(xmlNodePtr root, char * nodeID, data_src_t * model) { int i; xmlNodePtr node = xmlNewTextChild(root, NULL, (const xmlChar *) nodeID, NULL); for (i = 0; i < 3; i++) { xml_save_int_array(node, "enabled", model->enabled, i); xml_save_int_array(node, "type", model->type, i); } } void data_src_load(xmlDocPtr doc, xmlNodePtr node, char * nodeID, data_src_t ** model) { if (!xmlStrcmp(node->name, (const xmlChar *)nodeID)) { int i; xmlNodePtr cur; *model = data_src_new(); for (cur = node->xmlChildrenNode; cur != NULL; cur = cur->next) { for (i = 0; i < 3; i++) { xml_load_int_array(doc, cur, "enabled", (*model)->enabled, i); xml_load_int_array(doc, cur, "type", (*model)->type, i); } } #ifdef HAVE_CDDB (*model)->cddb_mask = 1; #else (*model)->cddb_mask = 0; #endif /* HAVE_CDDB */ } } void data_src_cell_toggled(GtkCellRendererToggle * cell, gchar * path, gpointer data) { GtkTreeIter iter; data_src_gui_t * gui = (data_src_gui_t *)data; if (gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(gui->list), &iter, path)) { gboolean bool; int type; gtk_tree_model_get(GTK_TREE_MODEL(gui->list), &iter, 0, &bool, 1, &type, -1); gtk_list_store_set(GTK_LIST_STORE(gui->list), &iter, 0, !bool && (type != DATA_SRC_CDDB || gui->model->cddb_mask), -1); } } data_src_gui_t * data_src_gui_new(data_src_t * model, GtkWidget * target_vbox) { data_src_gui_t * gui; int i; GtkTreeIter iter; GtkWidget * viewport; GtkWidget * tree_view; GtkTreeViewColumn * column; GtkCellRenderer * cell; if ((gui = (data_src_gui_t *)malloc(sizeof(data_src_gui_t))) == NULL) { fprintf(stderr, "build_store.c: data_src_gui_new(): malloc error\n"); return NULL; } gui->model = model; gui->list = gtk_list_store_new(3, G_TYPE_BOOLEAN, G_TYPE_INT, G_TYPE_STRING); tree_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(gui->list)); gtk_tree_view_set_reorderable(GTK_TREE_VIEW(tree_view), TRUE); cell = gtk_cell_renderer_toggle_new(); g_signal_connect(cell, "toggled", (GCallback)data_src_cell_toggled, gui); column = gtk_tree_view_column_new_with_attributes(_("Enabled"), cell, "active", 0, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), GTK_TREE_VIEW_COLUMN(column)); cell = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes(_("Source"), cell, "text", 2, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), GTK_TREE_VIEW_COLUMN(column)); viewport = gtk_viewport_new(NULL, NULL); for (i = 0; i < 3; i++) { gtk_list_store_append(gui->list, &iter); gtk_list_store_set(gui->list, &iter, 0, gui->model->enabled[i], 1, gui->model->type[i], -1); switch (gui->model->type[i]) { case DATA_SRC_CDDB: if (model->cddb_mask) { gtk_list_store_set(gui->list, &iter, 2, _("CDDB"), -1); } else { gtk_list_store_set(gui->list, &iter, 2, _("CDDB (not available)"), -1); } break; case DATA_SRC_META: gtk_list_store_set(gui->list, &iter, 2, _("Metadata"), -1); break; case DATA_SRC_FILE: gtk_list_store_set(gui->list, &iter, 2, _("Filesystem"), -1); break; } } gtk_container_add(GTK_CONTAINER(viewport), tree_view); gtk_box_pack_start(GTK_BOX(target_vbox), viewport, FALSE, FALSE, 5); return gui; } void data_src_gui_sync(data_src_gui_t * gui) { GtkTreeIter iter; int i; for (i = 0; gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(gui->list), &iter, NULL, i); i++) { gtk_tree_model_get(GTK_TREE_MODEL(gui->list), &iter, 0, gui->model->enabled + i, 1, gui->model->type + i, -1); } } capitalize_t * capitalize_new() { capitalize_t * model; if ((model = (capitalize_t *)calloc(1, sizeof(capitalize_t))) == NULL) { fprintf(stderr, "build_store.c: capitalize_new(): calloc error\n"); return NULL; } model->enabled = TRUE; model->pre_enabled = TRUE; model->low_enabled = TRUE; model->mode = CAP_ALL_WORDS; strncpy(model->pattern, "CD,a),b),c),d),I,II,III,IV,V,VI,VII,VIII,IX,X", MAXLEN-1); return model; } void capitalize_save(xmlNodePtr root, char * nodeID, capitalize_t * model) { xmlNodePtr node = xmlNewTextChild(root, NULL, (const xmlChar *) nodeID, NULL); xml_save_int(node, "enabled", model->enabled); xml_save_int(node, "pre_enabled", model->pre_enabled); xml_save_int(node, "low_enabled", model->low_enabled); xml_save_int(node, "mode", model->mode); xml_save_str(node, "pattern", model->pattern); } void capitalize_load(xmlDocPtr doc, xmlNodePtr node, char * nodeID, capitalize_t ** model) { if (!xmlStrcmp(node->name, (const xmlChar *)nodeID)) { xmlNodePtr cur; *model = capitalize_new(); for (cur = node->xmlChildrenNode; cur != NULL; cur = cur->next) { xml_load_int(doc, cur, "enabled", &(*model)->enabled); xml_load_int(doc, cur, "pre_enabled", &(*model)->pre_enabled); xml_load_int(doc, cur, "low_enabled", &(*model)->low_enabled); xml_load_int(doc, cur, "mode", &(*model)->mode); xml_load_str(doc, cur, "pattern", (*model)->pattern); } } } void capitalize_check_pre_toggled(GtkWidget * widget, gpointer data) { capitalize_gui_t * gui = (capitalize_gui_t *)data; gboolean state = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gui->check_pre)); gtk_widget_set_sensitive(gui->entry_pre, state); } void capitalize_check_toggled(GtkWidget * widget, gpointer data) { capitalize_gui_t * gui = (capitalize_gui_t *)data; gboolean state = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gui->check)); gtk_widget_set_sensitive(gui->combo, state); gtk_widget_set_sensitive(gui->check_pre, state); gtk_widget_set_sensitive(gui->check_low, state); if (state == FALSE) { gtk_widget_set_sensitive(gui->entry_pre, FALSE); } else { capitalize_check_pre_toggled(widget, data); } } capitalize_gui_t * capitalize_gui_new(capitalize_t * model, GtkWidget * target_vbox) { capitalize_gui_t * gui; GtkWidget * frame; GtkWidget * vbox; GtkWidget * table; if ((gui = (capitalize_gui_t *)malloc(sizeof(capitalize_gui_t))) == NULL) { fprintf(stderr, "build_store.c: capitalize_gui_new(): malloc error\n"); return NULL; } gui->model = model; frame = gtk_frame_new(_("Capitalization")); gtk_box_pack_start(GTK_BOX(target_vbox), frame, FALSE, FALSE, 5); vbox = gtk_vbox_new(FALSE, 0); gtk_container_set_border_width(GTK_CONTAINER(vbox), 5); gtk_container_add(GTK_CONTAINER(frame), vbox); table = gtk_table_new(2, 2, FALSE); gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0); gui->check = gtk_check_button_new_with_label(_("Capitalize: ")); gtk_widget_set_name(gui->check, "check_on_notebook"); gtk_table_attach(GTK_TABLE(table), gui->check, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 0, 0); g_signal_connect(G_OBJECT(gui->check), "toggled", G_CALLBACK(capitalize_check_toggled), gui); gui->combo = gtk_combo_box_new_text(); gtk_table_attach(GTK_TABLE(table), gui->combo, 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 5, 0); gtk_combo_box_append_text(GTK_COMBO_BOX(gui->combo), _("All words")); gtk_combo_box_append_text(GTK_COMBO_BOX(gui->combo), _("First word only")); gui->check_pre = gtk_check_button_new_with_label(_("Force case: ")); gtk_widget_set_name(gui->check_pre, "check_on_notebook"); gtk_table_attach(GTK_TABLE(table), gui->check_pre, 0, 1, 1, 2, GTK_FILL, GTK_FILL, 0, 5); g_signal_connect(G_OBJECT(gui->check_pre), "toggled", G_CALLBACK(capitalize_check_pre_toggled), gui); gui->entry_pre = gtk_entry_new(); gtk_entry_set_max_length(GTK_ENTRY(gui->entry_pre), MAXLEN-1); gtk_entry_set_text(GTK_ENTRY(gui->entry_pre), model->pattern); gtk_table_attach(GTK_TABLE(table), gui->entry_pre, 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, GTK_FILL, 5, 5); gui->check_low = gtk_check_button_new_with_label(_("Force other letters to lowercase")); gtk_widget_set_name(gui->check_low, "check_on_notebook"); gtk_box_pack_start(GTK_BOX(vbox), gui->check_low, TRUE, TRUE, 0); switch (model->mode) { case CAP_ALL_WORDS: gtk_combo_box_set_active(GTK_COMBO_BOX(gui->combo), 0); break; case CAP_FIRST_WORD: gtk_combo_box_set_active(GTK_COMBO_BOX(gui->combo), 1); break; } if (model->pre_enabled) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gui->check_pre), TRUE); } else { gtk_widget_set_sensitive(gui->combo, FALSE); } if (model->low_enabled) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gui->check_low), TRUE); } if (model->enabled) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gui->check), TRUE); } else { gtk_widget_set_sensitive(gui->combo, FALSE); gtk_widget_set_sensitive(gui->check_pre, FALSE); gtk_widget_set_sensitive(gui->entry_pre, FALSE); gtk_widget_set_sensitive(gui->check_low, FALSE); } return gui; } void capitalize_gui_sync(capitalize_gui_t * gui) { gui->model->enabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gui->check)); gui->model->pre_enabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gui->check_pre)); gui->model->low_enabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gui->check_low)); gui->model->mode = gtk_combo_box_get_active(GTK_COMBO_BOX(gui->combo)); strncpy(gui->model->pattern, gtk_entry_get_text(GTK_ENTRY(gui->entry_pre)), MAXLEN-1); gui->model->pre_stringv = g_strsplit(gtk_entry_get_text(GTK_ENTRY(gui->entry_pre)), ",", 0); } file_transform_t * file_transform_new() { file_transform_t * model; if ((model = (file_transform_t *)malloc(sizeof(file_transform_t))) == NULL) { fprintf(stderr, "build_store.c: file_transform_new(): malloc error\n"); return NULL; } model->regexp[0] = '\0'; model->replacement[0] = '\0'; model->rm_number = 0; model->rm_extension = 0; model->us_to_space = 1; model->rm_multi_spaces = 1; return model; } void file_transform_save(xmlNodePtr root, char * nodeID, file_transform_t * model) { xmlNodePtr node = xmlNewTextChild(root, NULL, (const xmlChar *) nodeID, NULL); xml_save_str(node, "regexp", model->regexp); xml_save_str(node, "replacement", model->replacement); xml_save_int(node, "rm_number", model->rm_number); xml_save_int(node, "rm_extension", model->rm_extension); xml_save_int(node, "us_to_space", model->us_to_space); xml_save_int(node, "rm_multi_spaces", model->rm_multi_spaces); } void file_transform_load(xmlDocPtr doc, xmlNodePtr node, char * nodeID, file_transform_t ** model) { if (!xmlStrcmp(node->name, (const xmlChar *)nodeID)) { xmlNodePtr cur; *model = file_transform_new(); for (cur = node->xmlChildrenNode; cur != NULL; cur = cur->next) { xml_load_str(doc, cur, "regexp", (*model)->regexp); xml_load_str(doc, cur, "replacement", (*model)->replacement); xml_load_int(doc, cur, "rm_number", &(*model)->rm_number); xml_load_int(doc, cur, "rm_extension", &(*model)->rm_extension); xml_load_int(doc, cur, "us_to_space", &(*model)->us_to_space); xml_load_int(doc, cur, "rm_multi_spaces", &(*model)->rm_multi_spaces); } } } file_transform_gui_t * file_transform_gui_new(file_transform_t * model, GtkWidget * target_vbox) { file_transform_gui_t * gui; GtkWidget * frame; GtkWidget * label; GtkWidget * vbox; GtkWidget * hbox; GtkWidget * table; GdkColor red = { 0, 30000, 0, 0 }; if ((gui = (file_transform_gui_t *)malloc(sizeof(file_transform_gui_t))) == NULL) { fprintf(stderr, "build_store.c: file_transform_gui_new(): malloc error\n"); return NULL; } gui->model = model; frame = gtk_frame_new(_("Regular expression")); gtk_box_pack_start(GTK_BOX(target_vbox), frame, FALSE, FALSE, 5); vbox = gtk_vbox_new(FALSE, 0); gtk_container_set_border_width(GTK_CONTAINER(vbox), 5); gtk_container_add(GTK_CONTAINER(frame), vbox); table = gtk_table_new(2, 2, FALSE); gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 5); hbox = gtk_hbox_new(FALSE, 0); label = gtk_label_new(_("Regexp:")); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5); gtk_table_attach(GTK_TABLE(table), hbox, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 0, 5); gui->entry_regexp = gtk_entry_new(); gtk_table_attach(GTK_TABLE(table), gui->entry_regexp, 1, 2, 0, 1, GTK_FILL | GTK_EXPAND, GTK_FILL, 5, 5); hbox = gtk_hbox_new(FALSE, 0); label = gtk_label_new(_("Replace:")); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5); gtk_table_attach(GTK_TABLE(table), hbox, 0, 1, 1, 2, GTK_FILL, GTK_FILL, 0, 5); gui->entry_replacement = gtk_entry_new(); gtk_table_attach(GTK_TABLE(table), gui->entry_replacement, 1, 2, 1, 2, GTK_FILL | GTK_EXPAND, GTK_FILL, 5, 5); gtk_entry_set_text(GTK_ENTRY(gui->entry_regexp), model->regexp); gtk_entry_set_text(GTK_ENTRY(gui->entry_replacement), model->replacement); hbox = gtk_hbox_new(FALSE, 0); gui->label_error = gtk_label_new(""); gtk_widget_modify_fg(gui->label_error, GTK_STATE_NORMAL, &red); gtk_box_pack_start(GTK_BOX(hbox), gui->label_error, FALSE, FALSE, 5); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); frame = gtk_frame_new(_("Predefined transformations")); gtk_box_pack_start(GTK_BOX(target_vbox), frame, FALSE, FALSE, 5); vbox = gtk_vbox_new(FALSE, 0); gtk_container_set_border_width(GTK_CONTAINER(vbox), 5); gtk_container_add(GTK_CONTAINER(frame), vbox); gui->check_rm_extension = gtk_check_button_new_with_label(_("Remove file extension")); gtk_widget_set_name(gui->check_rm_extension, "check_on_notebook"); gtk_box_pack_start(GTK_BOX(vbox), gui->check_rm_extension, FALSE, FALSE, 0); gui->check_rm_number = gtk_check_button_new_with_label(_("Remove leading number")); gtk_widget_set_name(gui->check_rm_number, "check_on_notebook"); gtk_box_pack_start(GTK_BOX(vbox), gui->check_rm_number, FALSE, FALSE, 0); gui->check_us_to_space = gtk_check_button_new_with_label(_("Convert underscore to space")); gtk_widget_set_name(gui->check_us_to_space, "check_on_notebook"); gtk_box_pack_start(GTK_BOX(vbox), gui->check_us_to_space, FALSE, FALSE, 0); gui->check_rm_multi_spaces = gtk_check_button_new_with_label(_("Trim leading, tailing and duplicate spaces")); gtk_widget_set_name(gui->check_rm_multi_spaces, "check_on_notebook"); gtk_box_pack_start(GTK_BOX(vbox), gui->check_rm_multi_spaces, FALSE, FALSE, 0); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gui->check_rm_number), model->rm_number); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gui->check_rm_extension), model->rm_extension); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gui->check_us_to_space), model->us_to_space); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gui->check_rm_multi_spaces), model->rm_multi_spaces); return gui; } int file_transform_gui_sync(file_transform_gui_t * gui) { int err; gui->model->rm_number = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gui->check_rm_number)); gui->model->rm_extension = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gui->check_rm_extension)); gui->model->us_to_space = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gui->check_us_to_space)); gui->model->rm_multi_spaces = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gui->check_rm_multi_spaces)); strncpy(gui->model->regexp, gtk_entry_get_text(GTK_ENTRY(gui->entry_regexp)), MAXLEN-1); strncpy(gui->model->replacement, gtk_entry_get_text(GTK_ENTRY(gui->entry_replacement)), MAXLEN-1); gtk_widget_hide(gui->label_error); if ((err = regcomp(&gui->model->compiled, gui->model->regexp, REG_EXTENDED | REG_ICASE))) { char msg[MAXLEN]; char * utf8; regerror(err, &gui->model->compiled, msg, MAXLEN); utf8 = g_filename_to_utf8(msg, -1, NULL, NULL, NULL); gtk_label_set_text(GTK_LABEL(gui->label_error), utf8); gtk_widget_show(gui->label_error); g_free(utf8); regfree(&gui->model->compiled); gtk_widget_grab_focus(gui->entry_regexp); return err; } if (gui->model->regexp[0] != '\0' && !regexec(&gui->model->compiled, "", 0, NULL, 0)) { gtk_label_set_text(GTK_LABEL(gui->label_error), _("Regexp matches empty string")); gtk_widget_show(gui->label_error); regfree(&gui->model->compiled); gtk_widget_grab_focus(gui->entry_regexp); return -1; } return 0; } build_store_t * build_store_new(GtkTreeIter * store_iter, char * file) { build_store_t * data; char * pfilter = NULL; int i; if ((data = (build_store_t *)calloc(1, sizeof(build_store_t))) == NULL) { fprintf(stderr, "build_store_new: calloc error\n"); return NULL; } #ifdef _WIN32 data->mutex = g_mutex_new(); #endif /* _WIN32 */ data->store_iter = *store_iter; data->file = strdup(file); data->type = BUILD_TYPE_STRICT; data->artist_dir_depth = 1; data->artist_sort_by = SORT_NAME_LOW; data->record_sort_by = SORT_YEAR; data->excl_enabled = 1; #ifdef HAVE_SNDFILE for (i = 0; valid_extensions_sndfile[i] != NULL; i++) { strcat(data->incl_pattern, "*."); strcat(data->incl_pattern, valid_extensions_sndfile[i]); strcat(data->incl_pattern, ","); } #endif /* HAVE_SNDFILE */ #ifdef HAVE_FLAC strcat(data->incl_pattern, "*.flac,"); #endif /* HAVE_FLAC */ #ifdef HAVE_OGG_VORBIS strcat(data->incl_pattern, "*.ogg,"); #endif /* HAVE_OGG_VORBIS */ #ifdef HAVE_MPEG for (i = 0; valid_extensions_mpeg[i] != NULL; i++) { strcat(data->incl_pattern, "*."); strcat(data->incl_pattern, valid_extensions_mpeg[i]); strcat(data->incl_pattern, ","); } #endif /* HAVE_MPEG */ #ifdef HAVE_SPEEX strcat(data->incl_pattern, "*.spx,"); #endif /* HAVE_SPEEX */ #ifdef HAVE_MPC strcat(data->incl_pattern, "*.mpc,"); #endif /* HAVE_MPC */ #ifdef HAVE_MAC strcat(data->incl_pattern, "*.ape,"); #endif /* HAVE_MAC */ #ifdef HAVE_MOD for (i = 0; valid_extensions_mod[i] != NULL; i++) { strcat(data->incl_pattern, "*."); strcat(data->incl_pattern, valid_extensions_mod[i]); strcat(data->incl_pattern, ","); } #endif /* HAVE_MOD */ #ifdef HAVE_WAVPACK strcat(data->incl_pattern, "*.wv,"); #endif /* HAVE_WAVPACK */ if ((pfilter = strrchr(data->incl_pattern, ',')) != NULL) { *pfilter = '\0'; } strcpy(data->excl_pattern, "*.jpg,*.jpeg,*.png,*.gif,*.pls,*.m3u,*.cue,*.xml,*.html,*.htm,*.txt,*.ini,*.nfo"); return data; } void build_store_save(build_store_t * data) { xmlDocPtr doc; xmlNodePtr root; xmlNodePtr node; doc = xmlParseFile(data->file); root = xmlDocGetRootElement(doc); for (node = root->xmlChildrenNode; node != NULL; node = node->next) { if (!xmlStrcmp(node->name, (const xmlChar *)"builder")) { xmlUnlinkNode(node); xmlFreeNode(node); break; } } node = xmlNewTextChild(root, NULL, (const xmlChar *)"builder", NULL); xml_save_int(node, "type", data->type); xml_save_str(node, "root", data->root); xml_save_int(node, "artist_dir_depth", data->artist_dir_depth); xml_save_int(node, "excl_enabled", data->excl_enabled); xml_save_str(node, "excl_pattern", data->excl_pattern); xml_save_int(node, "incl_enabled", data->incl_enabled); xml_save_str(node, "incl_pattern", data->incl_pattern); xml_save_int(node, "reset_existing_data", data->reset_existing_data); xml_save_int(node, "remove_dead_files", data->remove_dead_files); xml_save_int(node, "artist_sort_by", data->artist_sort_by); xml_save_int(node, "record_sort_by", data->record_sort_by); xml_save_int(node, "rec_add_year_to_comment", data->rec_add_year_to_comment); xml_save_int(node, "trk_rva_enabled", data->trk_rva_enabled); xml_save_int(node, "trk_comment_enabled", data->trk_comment_enabled); data_src_save(node, "data_src_artist", data->data_src_artist); data_src_save(node, "data_src_record", data->data_src_record); data_src_save(node, "data_src_track", data->data_src_track); capitalize_save(node, "capitalize_artist", data->capitalize_artist); capitalize_save(node, "capitalize_record", data->capitalize_record); capitalize_save(node, "capitalize_track", data->capitalize_track); file_transform_save(node, "file_transform_artist", data->file_transform_artist); file_transform_save(node, "file_transform_record", data->file_transform_record); file_transform_save(node, "file_transform_track", data->file_transform_track); xmlSaveFormatFile(data->file, doc, 1); xmlFreeDoc(doc); } int build_store_load(build_store_t * data, int test_only) { int found = 0; xmlDocPtr doc; xmlNodePtr root; xmlNodePtr node; doc = xmlParseFile(data->file); root = xmlDocGetRootElement(doc); for (node = root->xmlChildrenNode; node != NULL; node = node->next) { if (!xmlStrcmp(node->name, (const xmlChar *)"builder")) { found = 1; break; } } if (test_only) { xmlFreeDoc(doc); return found; } if (found) { xmlNodePtr cur; for (cur = node->xmlChildrenNode; cur != NULL; cur = cur->next) { xml_load_int(doc, cur, "type", &data->type); xml_load_str(doc, cur, "root", data->root); xml_load_int(doc, cur, "artist_dir_depth", &data->artist_dir_depth); xml_load_int(doc, cur, "excl_enabled", &data->excl_enabled); xml_load_str(doc, cur, "excl_pattern", data->excl_pattern); xml_load_int(doc, cur, "incl_enabled", &data->incl_enabled); xml_load_str(doc, cur, "incl_pattern", data->incl_pattern); xml_load_int(doc, cur, "reset_existing_data", &data->reset_existing_data); xml_load_int(doc, cur, "remove_dead_files", &data->remove_dead_files); xml_load_int(doc, cur, "artist_sort_by", &data->artist_sort_by); xml_load_int(doc, cur, "record_sort_by", &data->record_sort_by); xml_load_int(doc, cur, "rec_add_year_to_comment", &data->rec_add_year_to_comment); xml_load_int(doc, cur, "trk_rva_enabled", &data->trk_rva_enabled); xml_load_int(doc, cur, "trk_comment_enabled", &data->trk_comment_enabled); data_src_load(doc, cur, "data_src_artist", &data->data_src_artist); data_src_load(doc, cur, "data_src_record", &data->data_src_record); data_src_load(doc, cur, "data_src_track", &data->data_src_track); capitalize_load(doc, cur, "capitalize_artist", &data->capitalize_artist); capitalize_load(doc, cur, "capitalize_record", &data->capitalize_record); capitalize_load(doc, cur, "capitalize_track", &data->capitalize_track); file_transform_load(doc, cur, "file_transform_artist", &data->file_transform_artist); file_transform_load(doc, cur, "file_transform_record", &data->file_transform_record); file_transform_load(doc, cur, "file_transform_track", &data->file_transform_track); } } xmlFreeDoc(doc); return found; } xmlNodePtr build_store_get_xml_node(char * file) { xmlDocPtr doc; xmlNodePtr node; doc = xmlParseFile(file); if (doc == NULL) { return NULL; } node = xmlDocGetRootElement(doc); for (node = node->xmlChildrenNode; node != NULL; node = node->next) { if (!xmlStrcmp(node->name, (const xmlChar *)"builder")) { xmlNodePtr res = xmlCopyNode(node, 1); xmlFreeDoc(doc); return res; } } xmlFreeDoc(doc); return NULL; } void build_store_free(build_store_t * data) { #ifdef _WIN32 g_mutex_free(data->mutex); #endif /* _WIN32 */ free(data->file); g_strfreev(data->capitalize_artist->pre_stringv); data->capitalize_artist->pre_stringv = NULL; g_strfreev(data->capitalize_record->pre_stringv); data->capitalize_record->pre_stringv = NULL; g_strfreev(data->capitalize_track->pre_stringv); data->capitalize_track->pre_stringv = NULL; g_strfreev(data->excl_patternv); data->excl_patternv = NULL; g_strfreev(data->incl_patternv); data->incl_patternv = NULL; regfree(&data->file_transform_artist->compiled); regfree(&data->file_transform_record->compiled); regfree(&data->file_transform_track->compiled); free(data); } char * filter_string(const char * str) { int len; char * tmp; int i; int j; len = strlen(str); if (len == 0) { return NULL; } if ((tmp = (char *)malloc((len + 1) * sizeof(char))) == NULL) { fprintf(stderr, "build_store.c: filter_string(): malloc error\n"); return NULL; } for (i = 0, j = 0; i < len; i++) { if (str[i] != ' ' && str[i] != '.' && str[i] != ',' && str[i] != '?' && str[i] != '!' && str[i] != '&' && str[i] != '\'' && str[i] != '"' && str[i] != '-' && str[i] != '_' && str[i] != '/' && str[i] != '(' && str[i] != ')' && str[i] != '[' && str[i] != ']' && str[i] != '{' && str[i] != '}') { tmp[j++] = str[i]; } } tmp[j] = '\0'; return tmp; } int collate(const char * str1, const char * str2) { char * tmp1 = filter_string(str1); char * tmp2 = filter_string(str2); char * key1 = g_utf8_casefold(tmp1, -1); char * key2 = g_utf8_casefold(tmp2, -1); int i = g_utf8_collate(key1, key2); g_free(key1); g_free(key2); free(tmp1); free(tmp2); return i; } int store_contains_disc(GtkTreeIter * store_iter, GtkTreeIter * __artist_iter, GtkTreeIter * __record_iter, build_disc_t * disc) { int i, j, k; int n_tracks; GtkTreeIter artist_iter; GtkTreeIter record_iter; GtkTreeIter track_iter; build_track_t * ptrack = disc->tracks; for (n_tracks = 0; ptrack; ++n_tracks, ptrack = ptrack->next) ; i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &artist_iter, store_iter, i++)) { j = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &record_iter, &artist_iter, j++)) { int match = 1; if (gtk_tree_model_iter_n_children(GTK_TREE_MODEL(music_store), &record_iter) != n_tracks) { continue; } k = 0; ptrack = disc->tracks; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &track_iter, &record_iter, k++)) { track_data_t * data; gtk_tree_model_get(GTK_TREE_MODEL(music_store), &track_iter, MS_COL_DATA, &data, -1); if (strcmp(data->file, ptrack->filename)) { match = 0; break; } ptrack = ptrack->next; } if (match) { if (__artist_iter) { *__artist_iter = artist_iter; } if (__record_iter) { *__record_iter = record_iter; } return 1; } } } return 0; } int store_contains_track(GtkTreeIter * store_iter, GtkTreeIter * __track_iter, char * filename) { int i, j, k; GtkTreeIter artist_iter; GtkTreeIter record_iter; GtkTreeIter track_iter; i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &artist_iter, store_iter, i++)) { j = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &record_iter, &artist_iter, j++)) { k = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &track_iter, &record_iter, k++)) { track_data_t * data; gtk_tree_model_get(GTK_TREE_MODEL(music_store), &track_iter, MS_COL_DATA, &data, -1); if (!strcmp(data->file, filename)) { if (__track_iter) { *__track_iter = track_iter; } return 1; } } } } return 0; } void create_record(GtkTreeIter * artist_iter, GtkTreeIter * record_iter, build_disc_t * disc) { record_data_t * record_data; if ((record_data = (record_data_t *)calloc(1, sizeof(record_data_t))) == NULL) { fprintf(stderr, "create_record: calloc error\n"); return; } gtk_tree_store_append(music_store, record_iter, artist_iter); gtk_tree_store_set(music_store, record_iter, MS_COL_NAME, disc->record.final, MS_COL_SORT, disc->record.sort, MS_COL_DATA, record_data, -1); record_data->comment = strdup(disc->record.comment); record_data->year = atoi(disc->record.year); if (options.enable_ms_tree_icons) { gtk_tree_store_set(music_store, record_iter, MS_COL_ICON, icon_record, -1); } } void create_artist(GtkTreeIter * store_iter, GtkTreeIter * artist_iter, build_disc_t * disc) { artist_data_t * artist_data; if ((artist_data = (artist_data_t *)calloc(1, sizeof(artist_data_t))) == NULL) { fprintf(stderr, "create_artist: calloc error\n"); return; } gtk_tree_store_append(music_store, artist_iter, store_iter); gtk_tree_store_set(music_store, artist_iter, MS_COL_NAME, disc->artist.final, MS_COL_SORT, disc->artist.sort, MS_COL_DATA, artist_data, -1); if (options.enable_ms_tree_icons) { gtk_tree_store_set(music_store, artist_iter, MS_COL_ICON, icon_artist, -1); } } int store_get_iter_for_artist_and_record(GtkTreeIter * store_iter, GtkTreeIter * artist_iter, GtkTreeIter * record_iter, build_disc_t * disc) { int i; int j; i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), artist_iter, store_iter, i++)) { char * artist_name; gtk_tree_model_get(GTK_TREE_MODEL(music_store), artist_iter, MS_COL_NAME, &artist_name, -1); if (collate(disc->artist.final, artist_name)) { g_free(artist_name); continue; } j = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), record_iter, artist_iter, j++)) { char * record_name; gtk_tree_model_get(GTK_TREE_MODEL(music_store), record_iter, MS_COL_NAME, &record_name, -1); if (!collate(disc->record.final, record_name)) { g_free(record_name); g_free(artist_name); return RECORD_EXISTS; } g_free(record_name); } /* create record */ create_record(artist_iter, record_iter, disc); g_free(artist_name); return RECORD_NEW; } /* create both artist and record */ create_artist(store_iter, artist_iter, disc); create_record(artist_iter, record_iter, disc); return RECORD_NEW; } int store_get_iter_for_tracklist(GtkTreeIter * store_iter, GtkTreeIter * artist_iter, GtkTreeIter * record_iter, build_disc_t * disc, map_t ** artist_name_map) { int i; /* check if record already exists */ if (store_contains_disc(store_iter, artist_iter, record_iter, disc)) { if (disc->artist.unknown) { gtk_tree_store_set(music_store, artist_iter, MS_COL_NAME, disc->artist.final, MS_COL_SORT, disc->artist.sort, -1); } return RECORD_EXISTS; } /* no such record -- check if the artist of the record exists */ i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), artist_iter, store_iter, i++)) { char * artist_name; gtk_tree_model_get(GTK_TREE_MODEL(music_store), artist_iter, MS_COL_NAME, &artist_name, -1); if (collate(disc->artist.final, artist_name)) { g_free(artist_name); continue; } /* artist found, create record */ create_record(artist_iter, record_iter, disc); g_free(artist_name); return RECORD_NEW; } /* no such artist -- create both artist and record */ create_artist(store_iter, artist_iter, disc); create_record(artist_iter, record_iter, disc); /* start contest for artist name */ map_put(artist_name_map, disc->artist.final); return RECORD_NEW; } int artist_get_iter_for_tracklist(GtkTreeIter * artist_iter, GtkTreeIter * record_iter, build_disc_t * disc) { int i, j; int n_tracks; GtkTreeIter track_iter; build_track_t * ptrack = disc->tracks; /* check if record already exists */ for (n_tracks = 0; ptrack; ++n_tracks, ptrack = ptrack->next) ; i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), record_iter, artist_iter, i++)) { int match = 1; if (gtk_tree_model_iter_n_children(GTK_TREE_MODEL(music_store), record_iter) != n_tracks) { continue; } j = 0; ptrack = disc->tracks; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &track_iter, record_iter, j++)) { track_data_t * data; gtk_tree_model_get(GTK_TREE_MODEL(music_store), &track_iter, MS_COL_DATA, &data, -1); if (strcmp(data->file, ptrack->filename)) { match = 0; break; } ptrack = ptrack->next; } if (match) { return RECORD_EXISTS; } } /* no such record -- create it */ create_record(artist_iter, record_iter, disc); return RECORD_NEW; } void gen_check_filter_toggled(GtkWidget * widget, gpointer * data) { gboolean state = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); gtk_widget_set_sensitive(GTK_WIDGET(data), state); } void browse_button_clicked(GtkButton * button, gpointer data) { file_chooser_with_entry(_("Please select the root directory."), browser_window, GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, FILE_CHOOSER_FILTER_NONE, (GtkWidget *)data, options.currdir); } void snd_button_test_clicked(GtkWidget * widget, gpointer user_data) { build_store_t * data = (build_store_t *)user_data; char buf[MAXLEN]; int err; err = file_transform_gui_sync(data->snd_file_trans_gui); if (err) { gtk_entry_set_text(GTK_ENTRY(data->snd_entry_output), ""); return; } buf[0] = '\0'; strncpy(buf, (char *)gtk_entry_get_text(GTK_ENTRY(data->snd_entry_input)), MAXLEN-1); file_transform(buf, data->snd_file_trans_gui->model); regfree(&data->snd_file_trans_gui->model->compiled); gtk_entry_set_text(GTK_ENTRY(data->snd_entry_output), buf); } int build_type_dialog(build_store_t * build_data) { GtkWidget * dialog; GtkWidget * notebook; GtkWidget * radio_load; GtkWidget * radio_strict; GtkWidget * radio_loose; GtkWidget * vbox; GtkWidget * hbox; GtkWidget * label; dialog = gtk_dialog_new_with_buttons(_("Select build type"), GTK_WINDOW(browser_window), GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL); gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER); gtk_window_set_default_size(GTK_WINDOW(dialog), 400, -1); gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_REJECT); notebook = gtk_notebook_new(); gtk_notebook_set_show_tabs(GTK_NOTEBOOK(notebook), FALSE); gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), notebook); vbox = gtk_vbox_new(FALSE, 5); gtk_container_set_border_width(GTK_CONTAINER(vbox), 5); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox, NULL); radio_strict = gtk_radio_button_new_with_label(NULL, _("Directory driven")); gtk_widget_set_name(radio_strict, "check_on_notebook"); gtk_box_pack_start(GTK_BOX(vbox), radio_strict, FALSE, FALSE, 0); label = gtk_label_new(_("Follows the directory structure to identify the artists and\n" "records. The files are added on a record basis.")); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 30); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); radio_loose = gtk_radio_button_new_with_label_from_widget( GTK_RADIO_BUTTON(radio_strict), _("Independent")); gtk_widget_set_name(radio_loose, "check_on_notebook"); gtk_box_pack_start(GTK_BOX(vbox), radio_loose, FALSE, FALSE, 0); label = gtk_label_new(_("Recursive search from the root directory for audio files.\n" "The files are processed independently, so only metadata\n" "and filename transformation are available.")); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 30); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); radio_load = gtk_radio_button_new_with_label_from_widget( GTK_RADIO_BUTTON(radio_strict), _("Load settings from Music Store file")); if (build_store_load(build_data, 1)) { gtk_widget_set_name(radio_load, "check_on_notebook"); gtk_box_pack_start(GTK_BOX(vbox), radio_load, FALSE, FALSE, 0); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio_load), TRUE); } gtk_widget_show_all(dialog); if (aqualung_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radio_load))) { build_store_load(build_data, 0); } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radio_strict))) { build_data->type = BUILD_TYPE_STRICT; } else { build_data->type = BUILD_TYPE_LOOSE; } gtk_widget_destroy(dialog); return build_data->type; } gtk_widget_destroy(dialog); return -1; } int build_dialog(build_store_t * data) { GtkWidget * dialog; GtkWidget * notebook; GtkWidget * label; GtkWidget * table; GtkWidget * hbox; GtkWidget * vbox; GtkWidget * frame; /* General */ GtkWidget * gen_vbox; GtkWidget * gen_root_entry; GtkWidget * gen_browse_button; GtkWidget * gen_depth_combo = NULL; GtkWidget * gen_check_excl; GtkWidget * gen_check_incl; GtkWidget * gen_entry_excl; GtkWidget * gen_entry_incl; GtkWidget * gen_excl_frame; GtkWidget * gen_excl_frame_hbox; GtkWidget * gen_incl_frame; GtkWidget * gen_incl_frame_hbox; GtkWidget * gen_check_reset_data; GtkWidget * gen_check_remove_dead; /* Artist */ GtkWidget * art_vbox; GtkWidget * art_sort_combo; data_src_gui_t * art_src_gui; capitalize_gui_t * art_cap_gui; file_transform_gui_t * art_file_trans_gui; /* Record */ GtkWidget * rec_vbox; GtkWidget * rec_sort_combo; data_src_gui_t * rec_src_gui; capitalize_gui_t * rec_cap_gui; file_transform_gui_t * rec_file_trans_gui; GtkWidget * rec_check_add_year; /* Track */ GtkWidget * trk_vbox; data_src_gui_t * trk_src_gui; capitalize_gui_t * trk_cap_gui; file_transform_gui_t * trk_file_trans_gui; GtkWidget * trk_check_rva; GtkWidget * trk_check_comment; /* Sandbox */ GtkWidget * snd_vbox; GtkWidget * snd_button_test; int i, ret; dialog = gtk_dialog_new_with_buttons(_("Build/Update store"), GTK_WINDOW(browser_window), GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL); gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER); gtk_window_set_default_size(GTK_WINDOW(dialog), 400, -1); gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_REJECT); notebook = gtk_notebook_new(); gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_TOP); gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), notebook); /* General */ gen_vbox = gtk_vbox_new(FALSE, 0); gtk_container_set_border_width(GTK_CONTAINER(gen_vbox), 5); label = gtk_label_new(_("General")); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), gen_vbox, label); frame = gtk_frame_new(_("Directory structure")); gtk_box_pack_start(GTK_BOX(gen_vbox), frame, FALSE, FALSE, 5); table = gtk_table_new(2, 3, FALSE); gtk_container_set_border_width(GTK_CONTAINER(table), 5); gtk_container_add(GTK_CONTAINER(frame), table); label = gtk_label_new(_("Root path:")); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5); gtk_table_attach(GTK_TABLE(table), hbox, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 0, 5); gen_root_entry = gtk_entry_new (); gtk_entry_set_max_length(GTK_ENTRY(gen_root_entry), MAXLEN-1); gtk_entry_set_text(GTK_ENTRY(gen_root_entry), data->root); gtk_table_attach(GTK_TABLE(table), gen_root_entry, 1, 2, 0, 1, GTK_FILL | GTK_EXPAND, GTK_FILL, 0, 5); gen_browse_button = gui_stock_label_button(_("_Browse..."), GTK_STOCK_OPEN); gtk_table_attach(GTK_TABLE(table), gen_browse_button, 2, 3, 0, 1, GTK_FILL, GTK_FILL, 0, 5); g_signal_connect(G_OBJECT(gen_browse_button), "clicked", G_CALLBACK(browse_button_clicked), gen_root_entry); if (data->type == BUILD_TYPE_STRICT) { label = gtk_label_new(_("Structure:")); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5); gtk_table_attach(GTK_TABLE(table), hbox, 0, 1, 1, 2, GTK_FILL, GTK_FILL, 0, 0); gen_depth_combo = gtk_combo_box_new_text(); gtk_combo_box_append_text(GTK_COMBO_BOX(gen_depth_combo), _("root / record / track")); gtk_combo_box_append_text(GTK_COMBO_BOX(gen_depth_combo), _("root / artist / record / track")); gtk_combo_box_append_text(GTK_COMBO_BOX(gen_depth_combo), _("root / artist / artist / record / track")); gtk_combo_box_append_text(GTK_COMBO_BOX(gen_depth_combo), _("root / artist / artist / artist / record / track")); gtk_combo_box_set_active(GTK_COMBO_BOX(gen_depth_combo), data->artist_dir_depth); gtk_table_attach(GTK_TABLE(table), gen_depth_combo, 1, 3, 1, 2, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); } gen_excl_frame = gtk_frame_new(_("Exclude files matching wildcard")); gtk_box_pack_start(GTK_BOX(gen_vbox), gen_excl_frame, FALSE, FALSE, 5); gen_excl_frame_hbox = gtk_hbox_new(FALSE, 0); gtk_container_set_border_width(GTK_CONTAINER(gen_excl_frame_hbox), 5); gtk_container_add(GTK_CONTAINER(gen_excl_frame), gen_excl_frame_hbox); gen_check_excl = gtk_check_button_new(); gtk_widget_set_name(gen_check_excl, "check_on_notebook"); gtk_box_pack_start(GTK_BOX(gen_excl_frame_hbox), gen_check_excl, FALSE, FALSE, 0); gen_entry_excl = gtk_entry_new(); gtk_entry_set_max_length(GTK_ENTRY(gen_entry_excl), MAXLEN-1); gtk_entry_set_text(GTK_ENTRY(gen_entry_excl), data->excl_pattern); gtk_box_pack_end(GTK_BOX(gen_excl_frame_hbox), gen_entry_excl, TRUE, TRUE, 0); if (data->excl_enabled) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gen_check_excl), TRUE); } else { gtk_widget_set_sensitive(gen_entry_excl, FALSE); } g_signal_connect(G_OBJECT(gen_check_excl), "toggled", G_CALLBACK(gen_check_filter_toggled), gen_entry_excl); gen_incl_frame = gtk_frame_new(_("Include only files matching wildcard")); gtk_box_pack_start(GTK_BOX(gen_vbox), gen_incl_frame, FALSE, FALSE, 5); gen_incl_frame_hbox = gtk_hbox_new(FALSE, 0); gtk_container_set_border_width(GTK_CONTAINER(gen_incl_frame_hbox), 5); gtk_container_add(GTK_CONTAINER(gen_incl_frame), gen_incl_frame_hbox); gen_check_incl = gtk_check_button_new(); gtk_widget_set_name(gen_check_incl, "check_on_notebook"); gtk_box_pack_start(GTK_BOX(gen_incl_frame_hbox), gen_check_incl, FALSE, FALSE, 0); gen_entry_incl = gtk_entry_new(); gtk_entry_set_max_length(GTK_ENTRY(gen_entry_incl), MAXLEN-1); gtk_entry_set_text(GTK_ENTRY(gen_entry_incl), data->incl_pattern); gtk_box_pack_end(GTK_BOX(gen_incl_frame_hbox), gen_entry_incl, TRUE, TRUE, 0); if (data->incl_enabled) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gen_check_incl), TRUE); } else { gtk_widget_set_sensitive(gen_entry_incl, FALSE); } g_signal_connect(G_OBJECT(gen_check_incl), "toggled", G_CALLBACK(gen_check_filter_toggled), gen_entry_incl); gen_check_reset_data = gtk_check_button_new_with_label(_("Reread data for existing tracks")); gtk_widget_set_name(gen_check_reset_data, "check_on_notebook"); gtk_box_pack_start(GTK_BOX(gen_vbox), gen_check_reset_data, FALSE, FALSE, 0); if (data->reset_existing_data) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gen_check_reset_data), TRUE); } gen_check_remove_dead = gtk_check_button_new_with_label(_("Remove non-existing files from store")); gtk_widget_set_name(gen_check_remove_dead, "check_on_notebook"); gtk_box_pack_start(GTK_BOX(gen_vbox), gen_check_remove_dead, FALSE, FALSE, 0); if (data->remove_dead_files) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gen_check_remove_dead), TRUE); } /* Artist */ art_vbox = gtk_vbox_new(FALSE, 0); gtk_container_set_border_width(GTK_CONTAINER(art_vbox), 5); label = gtk_label_new(_("Artist")); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), art_vbox, label); if (data->data_src_artist == NULL) { data->data_src_artist = data_src_new(); if (data->type == BUILD_TYPE_LOOSE) { data->data_src_artist->enabled[DATA_SRC_FILE] = 0; } } if (data->type == BUILD_TYPE_LOOSE) { data->data_src_artist->cddb_mask = 0; for (i = 0; i < 3; i++) { if (data->data_src_artist->type[i] == DATA_SRC_CDDB) { data->data_src_artist->enabled[DATA_SRC_CDDB] = 0; break; } } } art_src_gui = data_src_gui_new(data->data_src_artist, art_vbox); if (data->file_transform_artist == NULL) { data->file_transform_artist = file_transform_new(); } art_file_trans_gui = file_transform_gui_new(data->file_transform_artist, art_vbox); if (data->capitalize_artist == NULL) { data->capitalize_artist = capitalize_new(); } art_cap_gui = capitalize_gui_new(data->capitalize_artist, art_vbox); frame = gtk_frame_new(_("Sort artists by")); gtk_box_pack_start(GTK_BOX(art_vbox), frame, FALSE, FALSE, 5); vbox = gtk_vbox_new(FALSE, 0); gtk_container_set_border_width(GTK_CONTAINER(vbox), 5); gtk_container_add(GTK_CONTAINER(frame), vbox); art_sort_combo = gtk_combo_box_new_text(); gtk_box_pack_start(GTK_BOX(vbox), art_sort_combo, FALSE, FALSE, 0); gtk_combo_box_append_text(GTK_COMBO_BOX(art_sort_combo), _("Artist name")); gtk_combo_box_append_text(GTK_COMBO_BOX(art_sort_combo), _("Artist name (lowercase)")); gtk_combo_box_append_text(GTK_COMBO_BOX(art_sort_combo), _("Directory name")); gtk_combo_box_append_text(GTK_COMBO_BOX(art_sort_combo), _("Directory name (lowercase)")); gtk_combo_box_set_active(GTK_COMBO_BOX(art_sort_combo), data->artist_sort_by); /* Record */ rec_vbox = gtk_vbox_new(FALSE, 0); gtk_container_set_border_width(GTK_CONTAINER(rec_vbox), 5); label = gtk_label_new(_("Record")); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), rec_vbox, label); if (data->data_src_record == NULL) { data->data_src_record = data_src_new(); if (data->type == BUILD_TYPE_LOOSE) { data->data_src_record->enabled[DATA_SRC_FILE] = 0; } } if (data->type == BUILD_TYPE_LOOSE) { data->data_src_record->cddb_mask = 0; for (i = 0; i < 3; i++) { if (data->data_src_record->type[i] == DATA_SRC_CDDB) { data->data_src_record->enabled[DATA_SRC_CDDB] = 0; break; } } } rec_src_gui = data_src_gui_new(data->data_src_record, rec_vbox); if (data->file_transform_record == NULL) { data->file_transform_record = file_transform_new(); } rec_file_trans_gui = file_transform_gui_new(data->file_transform_record, rec_vbox); if (data->capitalize_record == NULL) { data->capitalize_record = capitalize_new(); } rec_cap_gui = capitalize_gui_new(data->capitalize_record, rec_vbox); frame = gtk_frame_new(_("Sort records by")); gtk_box_pack_start(GTK_BOX(rec_vbox), frame, FALSE, FALSE, 5); vbox = gtk_vbox_new(FALSE, 0); gtk_container_set_border_width(GTK_CONTAINER(vbox), 5); gtk_container_add(GTK_CONTAINER(frame), vbox); rec_sort_combo = gtk_combo_box_new_text(); gtk_box_pack_start(GTK_BOX(vbox), rec_sort_combo, FALSE, FALSE, 0); gtk_combo_box_append_text(GTK_COMBO_BOX(rec_sort_combo), _("Record name")); gtk_combo_box_append_text(GTK_COMBO_BOX(rec_sort_combo), _("Record name (lowercase)")); gtk_combo_box_append_text(GTK_COMBO_BOX(rec_sort_combo), _("Directory name")); gtk_combo_box_append_text(GTK_COMBO_BOX(rec_sort_combo), _("Directory name (lowercase)")); gtk_combo_box_append_text(GTK_COMBO_BOX(rec_sort_combo), _("Year")); gtk_combo_box_set_active(GTK_COMBO_BOX(rec_sort_combo), data->record_sort_by); rec_check_add_year = gtk_check_button_new_with_label(_("Add year to the comments of new records")); gtk_widget_set_name(rec_check_add_year, "check_on_notebook"); gtk_box_pack_start(GTK_BOX(rec_vbox), rec_check_add_year, FALSE, FALSE, 0); if (data->rec_add_year_to_comment) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rec_check_add_year), TRUE); } /* Track */ trk_vbox = gtk_vbox_new(FALSE, 0); gtk_container_set_border_width(GTK_CONTAINER(trk_vbox), 5); label = gtk_label_new(_("Track")); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), trk_vbox, label); if (data->data_src_track == NULL) { data->data_src_track = data_src_new(); } if (data->type == BUILD_TYPE_LOOSE) { data->data_src_track->cddb_mask = 0; for (i = 0; i < 3; i++) { if (data->data_src_track->type[i] == DATA_SRC_CDDB) { data->data_src_track->enabled[DATA_SRC_CDDB] = 0; break; } } } trk_src_gui = data_src_gui_new(data->data_src_track, trk_vbox); if (data->file_transform_track == NULL) { data->file_transform_track = file_transform_new(); } trk_file_trans_gui = file_transform_gui_new(data->file_transform_track, trk_vbox); if (data->capitalize_track == NULL) { data->capitalize_track = capitalize_new(); } trk_cap_gui = capitalize_gui_new(data->capitalize_track, trk_vbox); trk_check_rva = gtk_check_button_new_with_label(_("Import Replaygain tag as manual RVA")); gtk_widget_set_name(trk_check_rva, "check_on_notebook"); gtk_box_pack_start(GTK_BOX(trk_vbox), trk_check_rva, FALSE, FALSE, 0); if (data->trk_rva_enabled) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(trk_check_rva), TRUE); } trk_check_comment = gtk_check_button_new_with_label(_("Import Comment tag")); gtk_widget_set_name(trk_check_comment, "check_on_notebook"); gtk_box_pack_start(GTK_BOX(trk_vbox), trk_check_comment, FALSE, FALSE, 0); if (data->trk_comment_enabled) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(trk_check_comment), TRUE); } /* Sandbox */ snd_vbox = gtk_vbox_new(FALSE, 0); gtk_container_set_border_width(GTK_CONTAINER(snd_vbox), 5); label = gtk_label_new(_("Sandbox")); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), snd_vbox, label); if (data->file_transform_sandbox == NULL) { data->file_transform_sandbox = file_transform_new(); } data->snd_file_trans_gui = file_transform_gui_new(data->file_transform_sandbox, snd_vbox); frame = gtk_frame_new(_("Sandbox")); gtk_box_pack_start(GTK_BOX(snd_vbox), frame, FALSE, FALSE, 5); table = gtk_table_new(2, 2, FALSE); gtk_container_set_border_width(GTK_CONTAINER(table), 5); gtk_container_add(GTK_CONTAINER(frame), table); hbox = gtk_hbox_new(FALSE, 0); label = gtk_label_new(_("Filename:")); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5); gtk_table_attach(GTK_TABLE(table), hbox, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 0, 5); data->snd_entry_input = gtk_entry_new(); gtk_table_attach(GTK_TABLE(table), data->snd_entry_input, 1, 2, 0, 1, GTK_FILL | GTK_EXPAND, GTK_FILL, 5, 5); snd_button_test = gtk_button_new_with_label(_("Test")); gtk_table_attach(GTK_TABLE(table), snd_button_test, 0, 1, 1, 2, GTK_FILL, GTK_FILL, 0, 5); g_signal_connect(G_OBJECT(snd_button_test), "clicked", G_CALLBACK(snd_button_test_clicked), data); data->snd_entry_output = gtk_entry_new(); gtk_table_attach(GTK_TABLE(table), data->snd_entry_output, 1, 2, 1, 2, GTK_FILL | GTK_EXPAND, GTK_FILL, 5, 5); /* run dialog */ gtk_widget_show_all(dialog); gtk_widget_hide(art_file_trans_gui->label_error); gtk_widget_hide(rec_file_trans_gui->label_error); gtk_widget_hide(trk_file_trans_gui->label_error); gtk_widget_hide(data->snd_file_trans_gui->label_error); gtk_widget_grab_focus(gen_root_entry); display: if (aqualung_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { char * proot = g_filename_from_utf8(gtk_entry_get_text(GTK_ENTRY(gen_root_entry)), -1, NULL, NULL, NULL); data->root[0] = '\0'; if (proot == NULL || proot[0] == '\0') { gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook), 0); gtk_widget_grab_focus(gen_root_entry); goto display; } normalize_filename(proot, data->root); g_free(proot); if (data->type == BUILD_TYPE_STRICT) { set_option_from_combo(gen_depth_combo, &data->artist_dir_depth); } set_option_from_toggle(gen_check_reset_data, &data->reset_existing_data); set_option_from_toggle(gen_check_remove_dead, &data->remove_dead_files); set_option_from_toggle(rec_check_add_year, &data->rec_add_year_to_comment); set_option_from_toggle(trk_check_rva, &data->trk_rva_enabled); set_option_from_toggle(trk_check_comment, &data->trk_comment_enabled); set_option_from_combo(art_sort_combo, &data->artist_sort_by); set_option_from_combo(rec_sort_combo, &data->record_sort_by); set_option_from_entry(gen_entry_excl, data->excl_pattern, MAXLEN); set_option_from_entry(gen_entry_incl, data->incl_pattern, MAXLEN); set_option_from_toggle(gen_check_excl, &data->excl_enabled); set_option_from_toggle(gen_check_incl, &data->incl_enabled); if (data->excl_enabled) { data->excl_patternv = g_strsplit(gtk_entry_get_text(GTK_ENTRY(gen_entry_excl)), ",", 0); } if (data->incl_enabled) { data->incl_patternv = g_strsplit(gtk_entry_get_text(GTK_ENTRY(gen_entry_incl)), ",", 0); } if (file_transform_gui_sync(art_file_trans_gui) != 0) { gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook), 1); goto display; } if (file_transform_gui_sync(rec_file_trans_gui) != 0) { gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook), 2); goto display; } if (file_transform_gui_sync(trk_file_trans_gui) != 0) { gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook), 3); goto display; } capitalize_gui_sync(art_cap_gui); capitalize_gui_sync(rec_cap_gui); capitalize_gui_sync(trk_cap_gui); data_src_gui_sync(art_src_gui); data_src_gui_sync(rec_src_gui); data_src_gui_sync(trk_src_gui); data->cddb_enabled = 0; for (i = 0; i < 3; i++) { if ((data->data_src_artist->type[i] == DATA_SRC_CDDB && data->data_src_artist->enabled[i]) || (data->data_src_record->type[i] == DATA_SRC_CDDB && data->data_src_record->enabled[i]) || (data->data_src_track->type[i] == DATA_SRC_CDDB && data->data_src_track->enabled[i])) { data->cddb_enabled = 1; break; } } data->meta_enabled = 0; for (i = 0; i < 3; i++) { if ((data->data_src_artist->type[i] == DATA_SRC_META && data->data_src_artist->enabled[i]) || (data->data_src_record->type[i] == DATA_SRC_META && data->data_src_record->enabled[i]) || (data->data_src_track->type[i] == DATA_SRC_META && data->data_src_track->enabled[i])) { data->meta_enabled = 1; break; } } build_store_save(data); ret = 1; } else { ret = 0; } gtk_widget_destroy(dialog); free(art_file_trans_gui); free(rec_file_trans_gui); free(trk_file_trans_gui); free(data->snd_file_trans_gui); free(art_cap_gui); free(rec_cap_gui); free(trk_cap_gui); free(art_src_gui); free(rec_src_gui); free(trk_src_gui); return ret; } void cancel_build(GtkButton * button, gpointer user_data) { build_store_t * data = (build_store_t *)user_data; data->cancelled = 1; if (data->prog_window) { unregister_toplevel_window(data->prog_window); gtk_widget_destroy(data->prog_window); data->prog_window = NULL; } } gboolean prog_window_close(GtkWidget * widget, GdkEvent * event, gpointer user_data) { cancel_build(NULL, user_data); return FALSE; } gboolean finish_build(gpointer user_data) { build_store_t * data = (build_store_t *)user_data; if (data->prog_window) { unregister_toplevel_window(data->prog_window); gtk_widget_destroy(data->prog_window); data->prog_window = NULL; } build_store_free(data); build_busy = 0; return FALSE; } void progress_window(build_store_t * data) { GtkWidget * table; GtkWidget * label; GtkWidget * vbox; GtkWidget * hbox; GtkWidget * hbuttonbox; data->prog_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); register_toplevel_window(data->prog_window, TOP_WIN_SKIN | TOP_WIN_TRAY); gtk_window_set_transient_for(GTK_WINDOW(data->prog_window), GTK_WINDOW(browser_window)); gtk_window_set_title(GTK_WINDOW(data->prog_window), _("Building store from filesystem")); gtk_window_set_position(GTK_WINDOW(data->prog_window), GTK_WIN_POS_CENTER); gtk_window_resize(GTK_WINDOW(data->prog_window), 430, 110); g_signal_connect(G_OBJECT(data->prog_window), "delete_event", G_CALLBACK(prog_window_close), data); gtk_container_set_border_width(GTK_CONTAINER(data->prog_window), 5); vbox = gtk_vbox_new(FALSE, 0); gtk_container_add(GTK_CONTAINER(data->prog_window), vbox); table = gtk_table_new(2, 2, FALSE); gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0); insert_label_entry(table, _("Processing:"), &data->prog_file_entry, NULL, 0, 1, FALSE); hbox = gtk_hbox_new(FALSE, 0); label = gtk_label_new(_("Action:")); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 0); gtk_table_attach(GTK_TABLE(table), hbox, 0, 1, 1, 2, GTK_FILL, GTK_FILL, 5, 5); hbox = gtk_hbox_new(FALSE, 0); data->prog_action_label = gtk_label_new(""); gtk_box_pack_start(GTK_BOX(hbox), data->prog_action_label, FALSE, TRUE, 0); gtk_table_attach(GTK_TABLE(table), hbox, 1, 2, 1, 2, GTK_FILL, GTK_FILL, 5, 5); gtk_box_pack_start(GTK_BOX(vbox), gtk_hseparator_new(), FALSE, TRUE, 5); hbuttonbox = gtk_hbutton_box_new(); gtk_box_pack_end(GTK_BOX(vbox), hbuttonbox, FALSE, TRUE, 0); gtk_button_box_set_layout(GTK_BUTTON_BOX(hbuttonbox), GTK_BUTTONBOX_END); data->prog_cancel_button = gui_stock_label_button (_("Abort"), GTK_STOCK_CANCEL); g_signal_connect(data->prog_cancel_button, "clicked", G_CALLBACK(cancel_build), data); gtk_container_add(GTK_CONTAINER(hbuttonbox), data->prog_cancel_button); gtk_widget_grab_focus(data->prog_cancel_button); gtk_widget_show_all(data->prog_window); } gboolean set_prog_file_entry_idle(gpointer user_data) { build_store_t * data = (build_store_t *)user_data; if (data->prog_window) { char * utf8 = NULL; AQUALUNG_MUTEX_LOCK(data->mutex); utf8 = g_filename_display_name(data->path); AQUALUNG_MUTEX_UNLOCK(data->mutex); gtk_entry_set_text(GTK_ENTRY(data->prog_file_entry), utf8); gtk_widget_grab_focus(data->prog_cancel_button); g_free(utf8); } return FALSE; } void set_prog_file_entry(build_store_t * data, char * path) { AQUALUNG_MUTEX_LOCK(data->mutex); strncpy(data->path, path, MAXLEN-1); AQUALUNG_MUTEX_UNLOCK(data->mutex); aqualung_idle_add(set_prog_file_entry_idle, data); } gboolean set_prog_action_label_idle(gpointer user_data) { build_store_t * data = (build_store_t *)user_data; if (data->prog_window) { AQUALUNG_MUTEX_LOCK(data->mutex); gtk_label_set_text(GTK_LABEL(data->prog_action_label), data->action); AQUALUNG_MUTEX_UNLOCK(data->mutex); } return FALSE; } void set_prog_action_label(build_store_t * data, char * action) { AQUALUNG_MUTEX_LOCK(data->mutex); strncpy(data->action, action, MAXLEN-1); AQUALUNG_MUTEX_UNLOCK(data->mutex); aqualung_idle_add(set_prog_action_label_idle, data); } void file_transform(char * buf, file_transform_t * model) { int i; char tmp[MAXLEN]; char * p = tmp; int offs = 0; regmatch_t regmatch[10]; tmp[0] = '\0'; if (model->regexp[0] != '\0') { p = buf; while (!regexec(&model->compiled, p + offs, 10, regmatch, 0)) { int i = 0; int b = strlen(model->replacement) - 1; strncat(tmp, p + offs, regmatch[0].rm_so); for (i = 0; i < b; i++) { if (model->replacement[i] == '\\' && isdigit(model->replacement[i+1])) { int j = model->replacement[i+1] - '0'; if (j == 0 || j > model->compiled.re_nsub) { i++; continue; } strncat(tmp, p + offs + regmatch[j].rm_so, regmatch[j].rm_eo - regmatch[j].rm_so); i++; } else { strncat(tmp, model->replacement + i, 1); } } strncat(tmp, model->replacement + i, 1); offs += regmatch[0].rm_eo; } if (!*tmp) { strncpy(tmp, p + offs, MAXLEN-1); } else { strcat(tmp, p + offs); } } else { strncpy(tmp, buf, MAXLEN-1); } p = tmp; if (model->rm_extension) { char * c = NULL; if ((c = strrchr(p, '.')) != NULL) { *c = '\0'; } } if (model->rm_number) { if (strlen(p) >= 3 && isdigit(*p) && isdigit(*(p + 1)) && (*(p + 2) == ' ' || *(p + 2) == '_' || *(p + 2) == '-' || *(p + 2) == '.')) { p += 3; while (*p && (*p == ' ' || *p == '_' || *p == '-' || *p == '.')) { ++p; } } if (*p) { buf[0] = '\0'; strcpy(buf, p); } } if (model->us_to_space) { for (i = 0; p[i]; i++) { if (p[i] == '_') { p[i] = ' '; } } } if (model->rm_multi_spaces) { char t[MAXLEN]; int j = 0; int len = strlen(p); for (i = 0; i < len; i++) { if (j == 0 && p[i] == ' ') { continue; } if (p[i] != ' ') { t[j++] = p[i]; continue; } else { if (i + 1 < len && p[i + 1] != ' ') { t[j++] = ' '; continue; } } } t[j] = '\0'; strcpy(p, t); } strncpy(buf, p, MAXLEN-1); } void cap_preserve(char * buf, capitalize_t * model) { int i = 0; int len_buf = 0; gchar * sub = NULL; gchar * haystack = NULL; if (model->pre_stringv[0] == NULL) { return; } len_buf = strlen(buf); haystack = g_utf8_strdown(buf, -1); for (i = 0; model->pre_stringv[i]; i++) { int len_cap = 0; int off = 0; gchar * needle = NULL; gchar * p = NULL; if (*(model->pre_stringv[i]) == '\0') { continue; } len_cap = strlen(model->pre_stringv[i]); needle = g_utf8_strdown(model->pre_stringv[i], -1); while ((sub = strstr(haystack + off, needle)) != NULL) { int len_sub = strlen(sub); if (((p = g_utf8_find_prev_char(haystack, sub)) == NULL || !g_unichar_isalpha(g_utf8_get_char(p))) && ((p = g_utf8_find_next_char(sub + len_cap - 1, NULL)) == NULL || !g_unichar_isalpha(g_utf8_get_char(p)))) { strncpy(buf + len_buf - len_sub, model->pre_stringv[i], len_cap); } off = len_buf - len_sub + len_cap; } g_free(needle); } g_free(haystack); } int cap_after(gunichar ch) { int i; gunichar * chars = NULL; chars = (gunichar *)malloc(8 * sizeof(gunichar)); chars[0] = g_utf8_get_char(" "); chars[1] = g_utf8_get_char("\t"); chars[2] = g_utf8_get_char("("); chars[3] = g_utf8_get_char("["); chars[4] = g_utf8_get_char("/"); chars[5] = g_utf8_get_char("\""); chars[6] = g_utf8_get_char("."); chars[7] = g_utf8_get_char("-"); for (i = 0; i < 8; i++) { if (chars[i] == ch) { free(chars); return 1; } } free(chars); return 0; } void capitalize(char * buf, capitalize_t * model) { int n; gchar * p = buf; gchar * result = NULL; gunichar prev = 0; gchar ** stringv = NULL; for (n = 0; *p; p = g_utf8_next_char(p)) { gunichar ch = g_utf8_get_char(p); gunichar new_ch; int len; if (prev == 0 || (model->mode == CAP_ALL_WORDS && cap_after(prev))) { new_ch = g_unichar_totitle(ch); } else { if (model->low_enabled) { new_ch = g_unichar_tolower(ch); } else { new_ch = ch; } } if ((stringv = (gchar **)realloc(stringv, (n + 2) * sizeof(gchar *))) == NULL) { fprintf(stderr, "build_store.c: capitalize(): realloc error\n"); return; } len = g_unichar_to_utf8(new_ch, NULL); if ((*(stringv + n) = (gchar *)malloc((len + 1) * sizeof(gchar))) == NULL) { fprintf(stderr, "build_store.c: capitalize(): malloc error\n"); return; } g_unichar_to_utf8(new_ch, *(stringv + n)); *(*(stringv + n) + len) = '\0'; prev = ch; ++n; } if (stringv == NULL) { return; } *(stringv + n) = NULL; result = g_strjoinv(NULL, stringv); strncpy(buf, result, MAXLEN-1); g_free(result); while (n >= 0) { free(*(stringv + n--)); } free(stringv); if (model->pre_enabled) { cap_preserve(buf, model); } } void process_meta(build_store_t * data, build_disc_t * disc) { build_track_t * ptrack; map_t * map_artist = NULL; map_t * map_record = NULL; map_t * map_year = NULL; for (ptrack = disc->tracks; ptrack; ptrack = ptrack->next) { char * tmp; file_decoder_t * fdec = file_decoder_new(); if (fdec == NULL) { fprintf(stderr, "process_meta: file_decoder_new() failed\n"); return; } if (file_decoder_open(fdec, ptrack->filename) == 0) { if (metadata_get_artist(fdec->meta, &tmp) && !is_all_wspace(tmp)) { map_put(&map_artist, tmp); } if (metadata_get_album(fdec->meta, &tmp) && !is_all_wspace(tmp)) { map_put(&map_record, tmp); } if (metadata_get_title(fdec->meta, &tmp) && !is_all_wspace(tmp)) { strncpy(ptrack->name[DATA_SRC_META], tmp, MAXLEN-1); } if (disc->record.year[0] == '\0' && metadata_get_date(fdec->meta, &tmp)) { int y = atoi(tmp); if (is_valid_year(y)) { map_put(&map_year, tmp); } } if (data->trk_rva_enabled) { ptrack->rva_found = metadata_get_rva(fdec->meta, &ptrack->rva); } else { ptrack->rva_found = 0; } if (data->trk_comment_enabled && metadata_get_comment(fdec->meta, &tmp) && !is_all_wspace(tmp)) { strncpy(ptrack->comment, tmp, MAXLEN-1); } file_decoder_close(fdec); } file_decoder_delete(fdec); } if (map_artist) { strncpy(disc->artist.name[DATA_SRC_META], map_get_max(map_artist), MAXLEN-1); } if (map_record) { strncpy(disc->record.name[DATA_SRC_META], map_get_max(map_record), MAXLEN-1); } if (map_year) { strncpy(disc->record.year, map_get_max(map_year), MAXLEN-1); } map_free(map_artist); map_free(map_record); map_free(map_year); } void add_new_track(GtkTreeIter * record_iter, build_track_t * ptrack, int i) { GtkTreeIter track_iter; char sort_name[16]; track_data_t * track_data; if ((track_data = (track_data_t *)calloc(1, sizeof(track_data_t))) == NULL) { fprintf(stderr, "add_new_track: calloc error\n"); return; } if (i == 0) { i = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(music_store), record_iter) + 1; } snprintf(sort_name, 15, "%02d", i); gtk_tree_store_append(music_store, &track_iter, record_iter); gtk_tree_store_set(music_store, &track_iter, MS_COL_NAME, ptrack->final, MS_COL_SORT, sort_name, MS_COL_DATA, track_data, -1); track_data->file = strdup(ptrack->filename); track_data->comment = strdup(ptrack->comment); track_data->duration = ptrack->duration; track_data->volume = 1.0f; if (ptrack->rva_found) { track_data->rva = ptrack->rva; track_data->use_rva = 1; } if (options.enable_ms_tree_icons) { gtk_tree_store_set(music_store, &track_iter, MS_COL_ICON, icon_track, -1); } } gboolean write_record_to_store(gpointer user_data) { build_store_t * data = (build_store_t *)user_data; build_track_t * ptrack; int result = 0; int i; GtkTreeIter record_iter; if (data->artist_iter_is_set) { result = artist_get_iter_for_tracklist(&data->artist_iter, &record_iter, data->disc); } else { result = store_get_iter_for_tracklist(&data->store_iter, &data->artist_iter, &record_iter, data->disc, &data->artist_name_map); data->artist_iter_is_set = 1; } if (data->artist_name_map != NULL && !data->disc->artist.unknown) { char * max = NULL; map_put(&data->artist_name_map, data->disc->artist.final); max = map_get_max(data->artist_name_map); gtk_tree_store_set(music_store, &data->artist_iter, MS_COL_NAME, max, MS_COL_SORT, data->disc->artist.sort, -1); } if (result == RECORD_NEW) { for (i = 0, ptrack = data->disc->tracks; ptrack; i++, ptrack = ptrack->next) { add_new_track(&record_iter, ptrack, i + 1); } } if (result == RECORD_EXISTS) { GtkTreeIter iter; if (data->disc->record.unknown) { gtk_tree_store_set(music_store, &record_iter, MS_COL_NAME, data->disc->record.final, -1); } i = 0; ptrack = data->disc->tracks; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &iter, &record_iter, i++)) { track_data_t * track_data; gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter, MS_COL_DATA, &track_data, -1); if (track_data->comment == NULL || track_data->comment[0] == '\0') { free_strdup(&track_data->comment, ptrack->comment); } gtk_tree_store_set(music_store, &iter, MS_COL_NAME, ptrack->final, -1); track_data->duration = ptrack->duration; if (ptrack->rva_found) { track_data->rva = ptrack->rva; track_data->use_rva = 1; } ptrack = ptrack->next; } } music_store_mark_changed(&data->store_iter); data->write_data_locked = 0; return FALSE; } gboolean write_track_to_store(gpointer user_data) { build_store_t * data = (build_store_t *)user_data; int result; GtkTreeIter record_iter; if (data->disc->flag) { /* track is present, reset data */ track_data_t * track_data; gtk_tree_model_get(GTK_TREE_MODEL(music_store), &data->disc->iter, MS_COL_DATA, &track_data, -1); if (track_data->comment == NULL || track_data->comment[0] == '\0') { free_strdup(&track_data->comment, data->disc->tracks->comment); } gtk_tree_store_set(music_store, &data->disc->iter, MS_COL_NAME, data->disc->tracks->final, -1); track_data->duration = data->disc->tracks->duration; if (data->disc->tracks->rva_found) { track_data->rva = data->disc->tracks->rva; track_data->use_rva = 1; } } else { GtkTreeIter artist_iter; result = store_get_iter_for_artist_and_record(&data->store_iter, &artist_iter, &record_iter, data->disc); add_new_track(&record_iter, data->disc->tracks, 0 /* append */); } music_store_mark_changed(&data->store_iter); data->write_data_locked = 0; return FALSE; } static int filter(const struct dirent * de) { return de->d_name[0] != '.'; } int filter_excl_incl(build_store_t * data, char * basename) { char * utf8 = g_filename_display_name(basename); if (data->excl_enabled) { int k; int match = 0; for (k = 0; data->excl_patternv[k]; k++) { if (*(data->excl_patternv[k]) == '\0') { continue; } if (fnmatch(data->excl_patternv[k], utf8, FNM_CASEFOLD) == 0) { match = 1; break; } } if (match) { g_free(utf8); return 0; } } if (data->incl_enabled) { int k; int match = 0; for (k = 0; data->incl_patternv[k]; k++) { if (*(data->incl_patternv[k]) == '\0') { continue; } if (fnmatch(data->incl_patternv[k], utf8, FNM_CASEFOLD) == 0) { match = 1; break; } } if (!match) { g_free(utf8); return 0; } } g_free(utf8); return 1; } void get_file_list(build_store_t * data, char * dir_record, build_disc_t * disc, int open) { int i, n; struct dirent ** ent_track; char basename[MAXLEN]; char filename[MAXLEN]; build_track_t * last_track = NULL; float duration = 0.0f; char * utf8; n = scandir(dir_record, &ent_track, filter, alphasort); for (i = 0; i < n; i++) { strncpy(basename, ent_track[i]->d_name, MAXLEN-1); snprintf(filename, MAXLEN-1, "%s/%s", dir_record, ent_track[i]->d_name); if (is_dir(filename) || !filter_excl_incl(data, basename)) { free(ent_track[i]); continue; } if (!open || (duration = get_file_duration(filename)) > 0.0f) { build_track_t * track; if ((track = (build_track_t *)calloc(1, sizeof(build_track_t))) == NULL) { fprintf(stderr, "build_store.c: get_file_list(): calloc error\n"); return; } else { strncpy(track->filename, filename, MAXLEN-1); utf8 = g_filename_display_name(ent_track[i]->d_name); strncpy(track->d_name, utf8, MAXLEN-1); g_free(utf8); track->duration = duration; track->rva = 1.0f; track->rva_found = 0; } if (last_track == NULL) { disc->tracks = last_track = track; } else { last_track->next = track; last_track = track; } } free(ent_track[i]); } if (n > 0) { free(ent_track); } } void process_filename(build_store_t * data, build_disc_t * disc) { int i, j; char * utf8; build_track_t * ptrack; /* Artist */ for (i = 0; i < 3; i++) { if (data->data_src_artist->enabled[i]) { if (data->data_src_artist->type[i] == DATA_SRC_FILE) { strncpy(disc->artist.name[DATA_SRC_FILE], disc->artist.d_name, MAXLEN-1); } if (disc->artist.name[data->data_src_artist->type[i]][0] != '\0') { strncpy(disc->artist.final, disc->artist.name[data->data_src_artist->type[i]], MAXLEN-1); break; } } } if (i == 3) { if (data->type == BUILD_TYPE_STRICT) { char tmp[MAXLEN]; snprintf(tmp, MAXLEN-1, "%s (%s)", _("Unknown Artist"), disc->artist.d_name); strncpy(disc->artist.final, tmp, MAXLEN-1); } else { strncpy(disc->artist.final, _("Unknown Artist"), MAXLEN-1); } disc->artist.unknown = 1; } else { file_transform(disc->artist.final, data->file_transform_artist); if (data->capitalize_artist->enabled) { capitalize(disc->artist.final, data->capitalize_artist); } } /* Record */ for (i = 0; i < 3; i++) { if (data->data_src_record->enabled[i]) { if (data->data_src_record->type[i] == DATA_SRC_FILE) { strncpy(disc->record.name[DATA_SRC_FILE], disc->record.d_name, MAXLEN-1); } if(disc->record.name[data->data_src_record->type[i]][0] != '\0') { strncpy(disc->record.final, disc->record.name[data->data_src_record->type[i]], MAXLEN-1); break; } } } if (i == 3) { if (data->type == BUILD_TYPE_STRICT) { char tmp[MAXLEN]; snprintf(tmp, MAXLEN-1, "%s (%s)", _("Unknown Record"), disc->record.d_name); strncpy(disc->record.final, tmp, MAXLEN-1); } else { strncpy(disc->record.final, disc->record.dirname, MAXLEN-1); } disc->record.unknown = 1; } else { file_transform(disc->record.final, data->file_transform_record); if (data->capitalize_record->enabled) { capitalize(disc->record.final, data->capitalize_record); } } /* Tracks */ for (i = 0, ptrack = disc->tracks; ptrack; i++, ptrack = ptrack->next) { strncpy(ptrack->name[DATA_SRC_FILE], ptrack->d_name, MAXLEN-1); for (j = 0; j < 3; j++) { if (data->data_src_track->enabled[j]) { if (data->data_src_track->type[i] == DATA_SRC_FILE) { strncpy(ptrack->name[DATA_SRC_FILE], ptrack->d_name, MAXLEN-1); } if (ptrack->name[data->data_src_track->type[j]][0] != '\0') { strncpy(ptrack->final, ptrack->name[data->data_src_track->type[j]], MAXLEN-1); break; } } } if (j == 3) { strncpy(ptrack->final, ptrack->d_name, MAXLEN-1); } else { file_transform(ptrack->final, data->file_transform_track); if (data->capitalize_track->enabled) { capitalize(ptrack->final, data->capitalize_track); } } } /* Artist and Record sort name */ switch (data->artist_sort_by) { case SORT_NAME: strncpy(disc->artist.sort, disc->artist.final, MAXLEN-1); break; case SORT_NAME_LOW: utf8 = g_utf8_strdown(disc->artist.final, -1); strncpy(disc->artist.sort, utf8, MAXLEN-1); g_free(utf8); break; case SORT_DIR: strncpy(disc->artist.sort, disc->artist.d_name, MAXLEN-1); break; case SORT_DIR_LOW: utf8 = g_utf8_strdown(disc->artist.d_name, -1); strncpy(disc->artist.sort, utf8, MAXLEN-1); g_free(utf8); break; } if (disc->artist.unknown) { char tmp[MAXLEN]; snprintf(tmp, MAXLEN-1, "0 %s", disc->artist.sort); strncpy(disc->artist.sort, tmp, MAXLEN-1); } switch (data->record_sort_by) { case SORT_YEAR: strncpy(disc->record.sort, disc->record.year, MAXLEN-1); break; case SORT_NAME: strncpy(disc->record.sort, disc->record.final, MAXLEN-1); break; case SORT_NAME_LOW: utf8 = g_utf8_strdown(disc->record.final, -1); strncpy(disc->record.sort, utf8, MAXLEN-1); g_free(utf8); break; case SORT_DIR: strncpy(disc->record.sort, disc->record.d_name, MAXLEN-1); break; case SORT_DIR_LOW: utf8 = g_utf8_strdown(disc->record.d_name, -1); strncpy(disc->record.sort, utf8, MAXLEN-1); g_free(utf8); break; } if (disc->record.unknown) { char tmp[MAXLEN]; snprintf(tmp, MAXLEN-1, "0 %s", disc->record.sort); strncpy(disc->record.sort, tmp, MAXLEN-1); } } #ifdef HAVE_CDDB static int cddb_init_query_data(build_disc_t * disc, int * ntracks, int ** frames, int * length) { int i; float len = 0.0f; float offset = 150.0f; /* leading 2 secs in frames */ build_track_t * ptrack = NULL; for (*ntracks = 0, ptrack = disc->tracks; ptrack; (*ntracks)++, ptrack = ptrack->next); if ((*frames = (int *)calloc(*ntracks, sizeof(int))) == NULL) { fprintf(stderr, "build_store.c: cddb_init_query_data(): calloc error\n"); return 1; } for (i = 0, ptrack = disc->tracks; ptrack; i++, ptrack = ptrack->next) { *((*frames) + i) = (int)offset; len += ptrack->duration; offset += 75.0f * ptrack->duration; } *length = (int)len; return 0; } #endif /* HAVE_CDDB */ void process_record(build_store_t * data, char * dir_record, char * artist_d_name, char * record_d_name) { struct timespec req_time; struct timespec rem_time; build_disc_t * disc = NULL; build_track_t * ptrack = NULL; char * utf8; req_time.tv_sec = 0; req_time.tv_nsec = 10000000; if ((disc = (build_disc_t *)calloc(1, sizeof(build_disc_t))) == NULL) { fprintf(stderr, "build_store.c: process_record(): calloc error\n"); return; } utf8 = g_filename_display_name(artist_d_name); strncpy(disc->artist.d_name, utf8, MAXLEN-1); g_free(utf8); utf8 = g_filename_display_name(record_d_name); strncpy(disc->record.d_name, utf8, MAXLEN-1); g_free(utf8); set_prog_action_label(data, _("Scanning files")); if (!data->reset_existing_data) { get_file_list(data, dir_record, disc, 0/* do not open*/); if (disc->tracks == NULL) { goto finish; } if (store_contains_disc(&data->store_iter, NULL, NULL, disc)) { goto finish; } } get_file_list(data, dir_record, disc, 1/* try to open*/); if (disc->tracks == NULL) { goto finish; } if (!data->reset_existing_data) { if (store_contains_disc(&data->store_iter, NULL, NULL, disc)) { goto finish; } } /* at this point the record either exists or should be re-read */ if (data->meta_enabled) { set_prog_action_label(data, _("Processing metadata")); process_meta(data, disc); } #ifdef HAVE_CDDB if (data->cddb_enabled) { int ntracks; int * frames; int length; char artist[MAXLEN]; char record[MAXLEN]; int year = 0; char ** tracks; int i; artist[0] = '\0'; record[0] = '\0'; set_prog_action_label(data, _("CDDB lookup")); if (cddb_init_query_data(disc, &ntracks, &frames, &length) != 0) { return; } if ((tracks = calloc(ntracks, sizeof(char *))) == NULL) { fprintf(stderr, "process_record: calloc error\n"); return; } for (i = 0; i < ntracks; i++) { if ((tracks[i] = calloc(1, MAXLEN * sizeof(char))) == NULL) { fprintf(stderr, "process_record: calloc error\n"); return; } } cddb_query_batch(ntracks, frames, length, artist, record, &year, tracks); if (artist[0] != '\0') { strncpy(disc->artist.name[DATA_SRC_CDDB], artist, MAXLEN-1); } if (record[0] != '\0') { strncpy(disc->record.name[DATA_SRC_CDDB], record, MAXLEN-1); } if (year > 0) { snprintf(disc->record.year, MAXLEN-1, "%d", year); } for (i = 0, ptrack = disc->tracks; ptrack && i < ntracks; i++, ptrack = ptrack->next) { strncpy(ptrack->name[DATA_SRC_CDDB], tracks[i], MAXLEN-1); free(tracks[i]); } free(tracks); } #endif /* HAVE_CDDB */ set_prog_action_label(data, _("Name transformation")); process_filename(data, disc); if (data->rec_add_year_to_comment) { strncpy(disc->record.comment, disc->record.year, MAXLEN-1); } /* wait for the gtk thread to update music_store */ data->write_data_locked = 1; data->disc = disc; aqualung_idle_add(write_record_to_store, data); while (data->write_data_locked) { nanosleep(&req_time, &rem_time); } finish: /* free tracklist */ for (ptrack = disc->tracks; ptrack; disc->tracks = ptrack) { ptrack = disc->tracks->next; free(disc->tracks); } free(disc); } void process_track(build_store_t * data, char * filename, char * d_name, float duration) { struct timespec req_time; struct timespec rem_time; GtkTreeIter iter_track; build_disc_t * disc; req_time.tv_sec = 0; req_time.tv_nsec = 10000000; if ((disc = (build_disc_t *)calloc(1, sizeof(build_disc_t))) == NULL) { fprintf(stderr, "build_store.c: process_track(): calloc error\n"); return; } if ((disc->tracks = (build_track_t *)calloc(1, sizeof(build_track_t))) == NULL) { fprintf(stderr, "build_store.c: process_track(): calloc error\n"); return; } else { char * utf8; utf8 = g_filename_display_name(d_name); strncpy(disc->tracks->d_name, utf8, MAXLEN-1); strncpy(disc->record.d_name, utf8, MAXLEN-1); strncpy(disc->artist.d_name, utf8, MAXLEN-1); g_free(utf8); utf8 = g_filename_display_name(filename); strncpy(disc->record.dirname, g_path_get_dirname(utf8), MAXLEN-1); g_free(utf8); strncpy(disc->tracks->filename, filename, MAXLEN-1); disc->tracks->duration = duration; disc->tracks->rva = 1.0f; disc->tracks->rva_found = 0; } disc->flag = store_contains_track(&data->store_iter, &iter_track, filename); disc->iter = iter_track; if (!data->reset_existing_data && disc->flag) { goto finish; } if (data->meta_enabled) { set_prog_action_label(data, _("Processing metadata")); process_meta(data, disc); } set_prog_action_label(data, _("Name transformation")); process_filename(data, disc); if (data->rec_add_year_to_comment) { strncpy(disc->record.comment, disc->record.year, MAXLEN-1); } /* wait for the gtk thread to update music_store */ data->write_data_locked = 1; data->disc = disc; aqualung_idle_add(write_track_to_store, data); while (data->write_data_locked) { nanosleep(&req_time, &rem_time); } finish: free(disc->tracks); free(disc); } void scan_artist_record(build_store_t * data, char * dir_artist, char * name_artist, int depth) { int i, n; struct dirent ** ent_record; char dir_record[MAXLEN]; data->artist_iter_is_set = 0; n = scandir(dir_artist, &ent_record, filter, alphasort); for (i = 0; i < n; i++) { if (data->cancelled) { break; } snprintf(dir_record, MAXLEN-1, "%s/%s", dir_artist, ent_record[i]->d_name); if (!is_dir(dir_record)) { free(ent_record[i]); continue; } set_prog_file_entry(data, dir_record); if (depth == 0) { data->artist_iter_is_set = 0; process_record(data, dir_record, ent_record[i]->d_name, ent_record[i]->d_name); if (data->artist_name_map != NULL) { map_free(data->artist_name_map); data->artist_name_map = NULL; } } else if (depth == 1) { process_record(data, dir_record, name_artist, ent_record[i]->d_name); } else { scan_artist_record(data, dir_record, ent_record[i]->d_name, depth - 1); } free(ent_record[i]); } while (i < n) { free(ent_record[i]); ++i; } if (n > 0) { free(ent_record); } if (data->artist_name_map != NULL) { map_free(data->artist_name_map); data->artist_name_map = NULL; } } void scan_recursively(build_store_t * data, char * dir) { int i, n; struct dirent ** ent; char path[MAXLEN]; n = scandir(dir, &ent, filter, alphasort); for (i = 0; i < n; i++) { if (data->cancelled) { break; } snprintf(path, MAXLEN-1, "%s/%s", dir, ent[i]->d_name); if (is_dir(path)) { scan_recursively(data, path); } else { float d; set_prog_file_entry(data, path); set_prog_action_label(data, _("Reading file")); if (filter_excl_incl(data, path) && (d = get_file_duration(path)) > 0.0f) { process_track(data, path, ent[i]->d_name, d); } } free(ent[i]); } while (i < n) { free(ent[i]); ++i; } if (n > 0) { free(ent); } } void remove_dead_files(build_store_t * data) { GtkTreeIter artist_iter; GtkTreeIter record_iter; GtkTreeIter track_iter; GtkTreeModel * model = GTK_TREE_MODEL(music_store); int i, j, k; track_data_t * track_data = NULL; char * artist = NULL; gboolean exists; if (!data->remove_dead_files) { return; } set_prog_action_label(data, _("Removing non-existing files")); gdk_threads_enter(); i = 0; while (gtk_tree_model_iter_nth_child(model, &artist_iter, &data->store_iter, i++)) { if (data->cancelled) { goto finish; } gtk_tree_model_get(model, &artist_iter, MS_COL_NAME, &artist, -1); gtk_entry_set_text(GTK_ENTRY(data->prog_file_entry), artist); gtk_widget_grab_focus(data->prog_cancel_button); j = 0; while (gtk_tree_model_iter_nth_child(model, &record_iter, &artist_iter, j++)) { if (data->cancelled) { goto finish; } k = 0; while (gtk_tree_model_iter_nth_child(model, &track_iter, &record_iter, k++)) { gtk_tree_model_get(model, &track_iter, MS_COL_DATA, &track_data, -1); gdk_threads_leave(); exists = g_file_test(track_data->file, G_FILE_TEST_EXISTS); gdk_threads_enter(); if (!exists) { store_file_remove_track(&track_iter); music_store_mark_changed(&data->store_iter); --k; } } if (!gtk_tree_model_iter_has_child(model, &record_iter)) { store_file_remove_record(&record_iter); music_store_mark_changed(&data->store_iter); --j; } } g_free(artist); if (!gtk_tree_model_iter_has_child(model, &artist_iter)) { store_file_remove_artist(&artist_iter); music_store_mark_changed(&data->store_iter); --i; } } finish: gdk_threads_leave(); } void * build_thread_strict(void * arg) { build_store_t * data = (build_store_t *)arg; AQUALUNG_THREAD_DETACH(); remove_dead_files(data); scan_artist_record(data, data->root, NULL, (data->artist_dir_depth == 0) ? 0 : (data->artist_dir_depth + 1)); aqualung_idle_add(finish_build, data); return NULL; } void * build_thread_loose(void * arg) { build_store_t * data = (build_store_t *)arg; AQUALUNG_THREAD_DETACH(); remove_dead_files(data); scan_recursively(data, data->root); aqualung_idle_add(finish_build, data); return NULL; } void build_store(GtkTreeIter * iter, char * file) { build_store_t * data; if ((data = build_store_new(iter, file)) == NULL) { return; } switch (build_type_dialog(data)) { case BUILD_TYPE_STRICT: if (build_dialog(data)) { progress_window(data); AQUALUNG_THREAD_CREATE(data->thread_id, NULL, build_thread_strict, data); build_busy = 1; } break; case BUILD_TYPE_LOOSE: if (build_dialog(data)) { progress_window(data); AQUALUNG_THREAD_CREATE(data->thread_id, NULL, build_thread_loose, data); build_busy = 1; } break; } } int build_is_busy(void) { return build_busy; } // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/common.h0000644000175000001440000000626511316204256013353 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: common.h 625 2007-05-26 09:37:09Z peterszilagyi $ */ #ifndef _COMMON_H #define _COMMON_H #include #define MAXLEN 1024 #define MAX_FONTNAME_LEN 256 #define MAX_COLORNAME_LEN 32 #define SELECTED 3 #define INSENSITIVE 4 #ifdef _WIN32 #define AQUALUNG_THREAD_DECLARE(thread_id) GThread * thread_id; #define AQUALUNG_THREAD_CREATE(id, attr, func, args) id=g_thread_create(func, args, TRUE, NULL); #define AQUALUNG_THREAD_JOIN(thread_id) g_thread_join(thread_id); #define AQUALUNG_THREAD_DETACH() ; #define AQUALUNG_MUTEX_DECLARE(mutex) GMutex * mutex; #define AQUALUNG_MUTEX_DECLARE_INIT(mutex) GMutex * mutex = NULL; #define AQUALUNG_MUTEX_LOCK(mutex) g_mutex_lock(mutex); #define AQUALUNG_MUTEX_UNLOCK(mutex) g_mutex_unlock(mutex); #define AQUALUNG_MUTEX_TRYLOCK(mutex) g_mutex_trylock(mutex) == TRUE #define AQUALUNG_COND_DECLARE(cond) GCond * cond; #define AQUALUNG_COND_DECLARE_INIT(cond) GCond * cond = NULL; #define AQUALUNG_COND_INIT(cond) cond = NULL; #define AQUALUNG_COND_SIGNAL(cond) g_cond_signal(cond); #define AQUALUNG_COND_TIMEDWAIT(cond, mutex, timeout) g_cond_timed_wait(cond, mutex, timeout); #define AQUALUNG_COND_WAIT(cond, mutex) g_cond_wait(cond, mutex); #else #define AQUALUNG_THREAD_DECLARE(thread_id) pthread_t thread_id; #define AQUALUNG_THREAD_CREATE(id, attr, func, args) pthread_create(&(id), attr, func, args); #define AQUALUNG_THREAD_JOIN(thread_id) pthread_join(thread_id, NULL); #define AQUALUNG_THREAD_DETACH() pthread_detach(pthread_self()); #define AQUALUNG_MUTEX_DECLARE(mutex) pthread_mutex_t mutex; #define AQUALUNG_MUTEX_DECLARE_INIT(mutex) pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; #define AQUALUNG_MUTEX_LOCK(mutex) pthread_mutex_lock(&(mutex)); #define AQUALUNG_MUTEX_UNLOCK(mutex) pthread_mutex_unlock(&(mutex)); #define AQUALUNG_MUTEX_TRYLOCK(mutex) pthread_mutex_trylock(&(mutex)) == 0 #define AQUALUNG_COND_DECLARE(cond) pthread_cond_t cond; #define AQUALUNG_COND_DECLARE_INIT(cond) pthread_cond_t cond = PTHREAD_COND_INITIALIZER; #define AQUALUNG_COND_INIT(cond) pthread_cond_init(&(cond), NULL); #define AQUALUNG_COND_SIGNAL(cond) pthread_cond_signal(&(cond)); #define AQUALUNG_COND_TIMEDWAIT(cond, mutex, timeout) pthread_cond_timedwait(&(cond), &(mutex), &(timeout)); #define AQUALUNG_COND_WAIT(cond, mutex) pthread_cond_wait(&(cond), &(mutex)); #endif /* _WIN32 */ #endif /* _COMMON_H */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/cdda.h0000644000175000001440000000470410731047243012753 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: cdda.h 925 2007-12-13 21:20:41Z peterszilagyi $ */ #ifndef _CDDA_H #define _CDDA_H #include #ifdef HAVE_CDDA #include #ifdef HAVE_CDDB #define _TMP_HAVE_CDDB 1 #undef HAVE_CDDB #endif /* HAVE_CDDB */ #include #include #ifdef HAVE_CDDB #undef HAVE_CDDB #endif /* HAVE_CDDB */ #ifdef _TMP_HAVE_CDDB #define HAVE_CDDB 1 #undef _TMP_HAVE_CDDB #endif /* _TMP_HAVE_CDDB */ #include "common.h" #define CDDA_DRIVES_MAX 16 #define CDDA_MAXLEN 256 typedef struct { int n_tracks; lsn_t toc[100]; unsigned long hash; unsigned long hash_prev; char record_name[MAXLEN]; char artist_name[MAXLEN]; char genre[MAXLEN]; int year; } cdda_disc_t; typedef struct { CdIo_t * cdio; int media_changed; int is_used; int swap_bytes; char device_path[CDDA_MAXLEN]; cdda_disc_t disc; } cdda_drive_t; char * cdda_displayed_device_path(char * device_path); void cdda_scanner_start(void); void cdda_scanner_stop(void); void cdda_timeout_start(void); void cdda_timeout_stop(void); void cdda_shutdown(void); void insert_cdda_drive_node(char * device_path); void remove_cdda_drive_node(char * device_path); void refresh_cdda_drive_node(char * device_path); void cdda_drive_info(cdda_drive_t * drive); void cdda_disc_info(cdda_drive_t * drive); unsigned long calc_cdda_hash(cdda_disc_t * disc); int cdda_hash_matches(char * filename, unsigned long hash); int cdda_get_n(char * device_path); cdda_drive_t * cdda_get_drive_by_device_path(char * device_path); cdda_drive_t * cdda_get_drive_by_spec_device_path(char * device_path); #endif /* HAVE_CDDA */ #endif /* _CDDA_H */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/cdda.c0000644000175000001440000004734610736426776013000 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: cdda.c 973 2008-01-01 11:16:27Z peterszilagyi $ */ #include #ifdef HAVE_CDDA #include #include #include #include #include #include #ifndef _WIN32 #include #endif /* !_WIN32 */ #ifdef HAVE_CDDB #define _TMP_HAVE_CDDB 1 #undef HAVE_CDDB #endif /* HAVE_CDDB */ #include #include #include #ifdef HAVE_CDDB #undef HAVE_CDDB #endif /* HAVE_CDDB */ #ifdef _TMP_HAVE_CDDB #define HAVE_CDDB 1 #undef _TMP_HAVE_CDDB #endif /* _TMP_HAVE_CDDB */ #include "common.h" #include "utils_gui.h" #include "options.h" #include "music_browser.h" #include "playlist.h" #include "gui_main.h" #include "rb.h" #include "i18n.h" #include "cdda.h" #include "store_cdda.h" extern options_t options; extern GdkPixbuf * icon_store; extern GdkPixbuf * icon_record; extern GdkPixbuf * icon_track; extern GdkPixbuf * icon_cdda; extern GdkPixbuf * icon_cdda_disc; extern GdkPixbuf * icon_cdda_nodisc; extern GtkTreeStore * music_store; extern GtkWidget * browser_window; typedef struct { int event_type; char * device_path; } cdda_notify_t; #define CDDA_NOTIFY_RB_SIZE (16*sizeof(cdda_notify_t)) #define CDDA_TIMEOUT_PERIOD 500 #define CDDA_EVENT_NEW_DRIVE 1 #define CDDA_EVENT_REMOVED_DRIVE 2 #define CDDA_EVENT_CHANGED_DRIVE 3 cdda_drive_t cdda_drives[CDDA_DRIVES_MAX]; AQUALUNG_THREAD_DECLARE(cdda_scanner_id) AQUALUNG_MUTEX_DECLARE(cdda_mutex) int cdda_scanner_working; guint cdda_timeout_tag; rb_t * cdda_notify_rb; static void cdda_log_handler(cdio_log_level_t level, const char message[]) { switch(level) { case CDIO_LOG_DEBUG: case CDIO_LOG_INFO: case CDIO_LOG_WARN: return; default: printf("cdio %d: %s\n", level, message); } } int cdda_get_first_free_slot(int * n) { int i; for (i = 0; i < CDDA_DRIVES_MAX; i++) { if (cdda_drives[i].device_path[0] == '\0') { *n = i; return 0; } } return -1; } cdda_drive_t * cdda_get_drive(int n) { if (n >= 0 && n < CDDA_DRIVES_MAX) { return &cdda_drives[n]; } else { return NULL; } } int cdda_get_n(char * device_path) { int i; for (i = 0; i < CDDA_DRIVES_MAX; i++) { if (!strcmp(device_path, cdda_drives[i].device_path)) return i; } return -1; } cdda_drive_t * cdda_get_drive_by_device_path(char * device_path) { int i; for (i = 0; i < CDDA_DRIVES_MAX; i++) { if (!strcmp(device_path, cdda_drives[i].device_path)) return &cdda_drives[i]; } return NULL; } cdda_drive_t * cdda_get_drive_by_spec_device_path(char * device_path) { if (strstr(device_path, "CDDA_DRIVE ") == device_path) { return cdda_get_drive_by_device_path(device_path + 11); } return NULL; } /* value should point to a buffer of size at least CDDA_MAXLEN */ /* ret 0 if OK, -1 if readlink error */ #ifndef _WIN32 int symlink_deref_absolute(char * symlink, char * path) { int ret = readlink(symlink, path, CDDA_MAXLEN-1); if (ret < 0) return -1; path[ret] = '\0'; if (!g_path_is_absolute(path)) { char tmp[CDDA_MAXLEN]; char * dir = g_path_get_dirname(symlink); snprintf(tmp, CDDA_MAXLEN-1, "%s/%s", dir, path); strcpy(path, tmp); g_free(dir); } return 0; } #endif /* !_WIN32 */ /* return 1 if drives[i] is a symlink to a drive path * also present in the drives[] string array, or the * second, third, ... of symlinks pointing to the same * physical device path. Return 0 else. */ int cdda_skip_extra_symlink(char ** drives, int i) { #ifndef _WIN32 int j; char path[CDDA_MAXLEN]; if (!g_file_test(drives[i], G_FILE_TEST_IS_SYMLINK)) return 0; if ((symlink_deref_absolute(drives[i], path)) != 0) return 1; /* have the destination of the symlink in our device list */ for (j = 0; drives[j] != NULL; j++) { if (i == j) continue; if (strcmp(drives[j], path) == 0) { return 1; } } /* have another symlink to the same destination with a smaller index */ for (j = 0; (j < i) && (drives[j] != NULL); j++) { char path2[CDDA_MAXLEN]; if (!g_file_test(drives[j], G_FILE_TEST_IS_SYMLINK)) continue; if ((symlink_deref_absolute(drives[j], path2)) != 0) continue; if (strcmp(path, path2) == 0) return 1; } return 0; #else return 0; #endif /* !_WIN32 */ } unsigned long calc_cdda_hash(cdda_disc_t * disc) { unsigned long result = 0; unsigned long tmp; unsigned long discid; int i; if (disc->n_tracks == 0) { return 0; } for (i = 0; i < disc->n_tracks; i++) { tmp = (disc->toc[i] + 150) / 75; do { result += tmp % 10; tmp /= 10; } while (tmp != 0); } discid = (result % 0xff) << 24 | (disc->toc[disc->n_tracks] / 75) << 8 | disc->n_tracks; return discid; } int cdda_hash_matches(char * filename, unsigned long hash) { char device_path[CDDA_MAXLEN]; unsigned long fhash; unsigned int track; if (sscanf(filename, "CDDA %s %lX %u", device_path, &fhash, &track) < 3) { return 0; } return fhash == hash; } /* return 0 if OK, -1 if drive is apparently not available */ int cdda_scan_drive(char * device_path, cdda_drive_t * cdda_drive) { track_t tracks; track_t first_track; track_t last_track; track_t skipped = 0; int i, n = 0; cdrom_drive_t * d; if (cdda_drive->cdio == NULL) { cdda_drive->cdio = cdio_open(device_path, DRIVER_DEVICE); if (!cdda_drive->cdio) { return -1; } strncpy(cdda_drive->device_path, device_path, CDDA_MAXLEN-1); } cdda_drive->disc.n_tracks = 0; tracks = cdio_get_num_tracks(cdda_drive->cdio); if (tracks < 1 || tracks >= 100) { cdda_drive->disc.hash_prev = cdda_drive->disc.hash; cdda_drive->disc.hash = 0L; return 0; } d = cdio_cddap_identify_cdio(cdda_drive->cdio, 0, NULL); if (d == NULL) { return -1; } first_track = cdio_get_first_track_num(cdda_drive->cdio); last_track = cdio_get_last_track_num(cdda_drive->cdio); for (i = first_track; i <= last_track; i++) { if (!cdio_cddap_track_audiop(d, i)) { skipped = i; last_track = i-1; break; } } cdio_cddap_close_no_free_cdio(d); if (last_track < first_track) { return 0; } cdda_drive->disc.n_tracks = last_track - first_track + 1; for (i = first_track; i <= last_track; i++) { lsn_t lsn = cdio_get_track_lsn(cdda_drive->cdio, i); if (lsn != CDIO_INVALID_LSN) { cdda_drive->disc.toc[n++] = lsn; } } if (skipped == 0) { cdda_drive->disc.toc[n] = cdio_get_track_lsn(cdda_drive->cdio, CDIO_CDROM_LEADOUT_TRACK); } else { cdda_drive->disc.toc[n] = cdio_get_track_lsn(cdda_drive->cdio, skipped); if ((cdda_drive->disc.toc[n] - cdda_drive->disc.toc[n-1]) >= 11400) { /* compensate end of track with multisession offset */ cdda_drive->disc.toc[n] -= 11400; } } cdda_drive->disc.hash_prev = cdda_drive->disc.hash; cdda_drive->disc.hash = calc_cdda_hash(&cdda_drive->disc); if (cdda_drive->disc.hash != cdda_drive->disc.hash_prev) { strncpy(cdda_drive->disc.artist_name, _("Unknown Artist"), MAXLEN-1); strncpy(cdda_drive->disc.record_name, _("Unknown Record"), MAXLEN-1); cdda_drive->swap_bytes = -1; /* unknown */ } return 0; } void cdda_send_event(int event_type, char * drive) { cdda_notify_t notify; /* If there is no space for the message, it is dropped. * This may happen if GUI gets blocked (unable to run cdda_timeout_callback() * for several seconds), however it is not anticipated to happen very often. * In such case these events are not very much of use, anyway. */ if (rb_write_space(cdda_notify_rb) >= sizeof(cdda_notify_t)) { notify.event_type = event_type; notify.device_path = strdup(drive); rb_write(cdda_notify_rb, (char *)¬ify, sizeof(cdda_notify_t)); } } void cdda_scan_all_drives(void) { char ** drives = NULL; char touched[CDDA_DRIVES_MAX]; int i; for (i = 0; i < CDDA_DRIVES_MAX; i++) { if (cdda_drives[i].cdio != NULL) { cdda_drives[i].media_changed = options.cdda_force_drive_rescan ? 1 : cdio_get_media_changed(cdda_drives[i].cdio); if (cdda_drives[i].media_changed) { cdio_destroy(cdda_drives[i].cdio); cdda_drives[i].cdio = NULL; } } } drives = cdio_get_devices(DRIVER_DEVICE); if (!drives) return; for (i = 0; i < CDDA_DRIVES_MAX; i++) touched[i] = 0; for (i = 0; (drives[i] != NULL) && (i < CDDA_DRIVES_MAX); i++) { int n; /* see if drives[i] is already known to us... */ cdda_drive_t * d = cdda_get_drive_by_device_path(drives[i]); if (d != NULL) { /* yes */ n = cdda_get_n(drives[i]); touched[n] = 1; if (cdda_drives[n].media_changed) { cdda_scan_drive(drives[i], cdda_get_drive(n)); if ((cdda_drives[n].disc.hash == 0L) || (cdda_drives[n].disc.hash != cdda_drives[n].disc.hash_prev)) { /* EVENT refresh disc data */ cdda_send_event(CDDA_EVENT_CHANGED_DRIVE, drives[i]); } } } else { /* no, scan the drive */ if (cdda_skip_extra_symlink(drives, i)) continue; if (cdda_get_first_free_slot(&n) < 0) { printf("cdda.c: error: too many CD drives\n"); return; } if (cdda_scan_drive(drives[i], cdda_get_drive(n)) >= 0) { touched[n] = 1; /* EVENT newly discovered drive */ cdda_send_event(CDDA_EVENT_NEW_DRIVE, drives[i]); } } } cdio_free_device_list(drives); /* remove all drives that were not touched (those that disappeared) */ for (i = 0; i < CDDA_DRIVES_MAX; i++) { if ((cdda_drives[i].device_path[0] != '\0') && (touched[i] == 0)) { /* EVENT removed drive */ cdda_send_event(CDDA_EVENT_REMOVED_DRIVE, cdda_drives[i].device_path); cdio_destroy(cdda_drives[i].cdio); memset(cdda_drives + i, 0, sizeof(cdda_drive_t)); } } } void * cdda_scanner(void * arg) { int i = 0; cdio_log_set_handler(cdda_log_handler); AQUALUNG_MUTEX_LOCK(cdda_mutex) cdda_scan_all_drives(); AQUALUNG_MUTEX_UNLOCK(cdda_mutex) while (cdda_scanner_working) { struct timespec req_time; struct timespec rem_time; req_time.tv_sec = 0; req_time.tv_nsec = 100000000; nanosleep(&req_time, &rem_time); if (i == 50) { /* scan every 5 seconds */ AQUALUNG_MUTEX_LOCK(cdda_mutex) cdda_scan_all_drives(); AQUALUNG_MUTEX_UNLOCK(cdda_mutex) i = 0; } ++i; } AQUALUNG_MUTEX_LOCK(cdda_mutex) for (i = 0; i < CDDA_DRIVES_MAX; i++) { if (cdda_drives[i].cdio != NULL) { cdio_destroy(cdda_drives[i].cdio); memset(cdda_drives + i, 0, sizeof(cdda_drive_t)); } } AQUALUNG_MUTEX_UNLOCK(cdda_mutex) return NULL; } gint cdda_timeout_callback(gpointer data) { cdda_notify_t notify; while (rb_read_space(cdda_notify_rb) >= sizeof(cdda_notify_t)) { rb_read(cdda_notify_rb, (char *)¬ify, sizeof(cdda_notify_t)); switch (notify.event_type) { case CDDA_EVENT_NEW_DRIVE: AQUALUNG_MUTEX_LOCK(cdda_mutex) insert_cdda_drive_node(notify.device_path); AQUALUNG_MUTEX_UNLOCK(cdda_mutex) free(notify.device_path); break; case CDDA_EVENT_CHANGED_DRIVE: AQUALUNG_MUTEX_LOCK(cdda_mutex) refresh_cdda_drive_node(notify.device_path); AQUALUNG_MUTEX_UNLOCK(cdda_mutex) free(notify.device_path); break; case CDDA_EVENT_REMOVED_DRIVE: AQUALUNG_MUTEX_LOCK(cdda_mutex) remove_cdda_drive_node(notify.device_path); AQUALUNG_MUTEX_UNLOCK(cdda_mutex) free(notify.device_path); break; } } return TRUE; } void cdda_timeout_start(void) { cdda_timeout_tag = aqualung_timeout_add(CDDA_TIMEOUT_PERIOD, cdda_timeout_callback, NULL); } void cdda_timeout_stop(void) { g_source_remove(cdda_timeout_tag); } void cdda_scanner_start(void) { if (cdda_scanner_working) { return; } cdda_notify_rb = rb_create(CDDA_NOTIFY_RB_SIZE); #ifdef _WIN32 cdda_mutex = g_mutex_new(); #endif /* _WIN32 */ cdda_timeout_start(); cdda_scanner_working = 1; AQUALUNG_THREAD_CREATE(cdda_scanner_id, NULL, cdda_scanner, NULL) } void cdda_scanner_stop(void) { cdda_scanner_working = 0; AQUALUNG_THREAD_JOIN(cdda_scanner_id) cdda_timeout_callback(NULL); /* cleanup any leftover messages */ cdda_timeout_stop(); #ifdef _WIN32 g_mutex_free(cdda_mutex); #endif /* _WIN32 */ rb_free(cdda_notify_rb); } /* For some odd reason, drive names on Win32 begin with "\\.\" so eg. D: has a * device_path of "\\.\D:" This function gets rid of that. Returns a pointer to * the same buffer that is passed in (no mem allocated). */ char * cdda_displayed_device_path(char * device_path) { #ifdef _WIN32 if (strstr(device_path, "\\\\.\\") == device_path) { return device_path + 4; } else { return device_path; } #else return device_path; #endif /* _WIN32 */ } /* Returns 0 on success, 1 on failure */ int update_track_data_from_cdtext(cdda_drive_t * drive, GtkTreeIter * iter_drive) { CdIo_t * cdio; cdtext_t * cdtext; GtkTreeIter iter; int i; int ret = 0; cdio = cdio_open(drive->device_path, DRIVER_UNKNOWN); cdtext = cdio_get_cdtext(cdio, 0); if (cdtext == NULL) { ret = 1; } else { char tmp[MAXLEN]; tmp[0] = '\0'; if (cdtext->field[CDTEXT_PERFORMER] != NULL && *(cdtext->field[CDTEXT_PERFORMER]) != '\0') { strncat(tmp, cdtext->field[CDTEXT_PERFORMER], MAXLEN-1); strncpy(drive->disc.artist_name, cdtext->field[CDTEXT_PERFORMER], MAXLEN-1); } else { ret = 1; } strncat(tmp, ": ", MAXLEN - strlen(tmp) - 1); if (cdtext->field[CDTEXT_TITLE] != NULL && *(cdtext->field[CDTEXT_TITLE]) != '\0') { strncat(tmp, cdtext->field[CDTEXT_TITLE], MAXLEN - strlen(tmp) - 1); strncpy(drive->disc.record_name, cdtext->field[CDTEXT_TITLE], MAXLEN-1); } else { ret = 1; } if (ret == 0) { gtk_tree_store_set(music_store, iter_drive, MS_COL_NAME, tmp, -1); } } i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &iter, iter_drive, i++)) { cdtext = cdio_get_cdtext(cdio, i); if (cdtext == NULL) { ret = 1; continue; } if (cdtext->field[CDTEXT_TITLE] != NULL && *(cdtext->field[CDTEXT_TITLE]) != '\0') { gtk_tree_store_set(music_store, &iter, MS_COL_NAME, cdtext->field[CDTEXT_TITLE], -1); } else { ret = 1; } } cdio_destroy(cdio); return ret; } void update_track_data(cdda_drive_t * drive, GtkTreeIter iter_drive) { int i; for (i = 0; i < drive->disc.n_tracks; i++) { GtkTreeIter iter_track; char title[MAXLEN]; char path[CDDA_MAXLEN]; char sort[16]; cdda_track_t * data; snprintf(title, MAXLEN-1, "Track %d", i+1); snprintf(path, CDDA_MAXLEN-1, "CDDA %s %lX %d", drive->device_path, drive->disc.hash, i+1); snprintf(sort, 15, "%02d", i+1); if ((data = (cdda_track_t *)malloc(sizeof(cdda_track_t))) == NULL) { fprintf(stderr, "update_track_data: malloc error\n"); return; } data->path = strdup(path); data->duration = (drive->disc.toc[i+1] - drive->disc.toc[i]) / 75.0; gtk_tree_store_append(music_store, &iter_track, &iter_drive); gtk_tree_store_set(music_store, &iter_track, MS_COL_NAME, title, MS_COL_SORT, sort, MS_COL_DATA, data, -1); if (options.enable_ms_tree_icons) { gtk_tree_store_set(music_store, &iter_track, MS_COL_ICON, icon_track, -1); } } if (update_track_data_from_cdtext(drive, &iter_drive) != 0) { #ifdef HAVE_CDDB cdda_record_auto_query_cddb(&iter_drive); #else if (options.cdda_add_to_playlist) { cdda_add_to_playlist(&iter_drive, drive->disc.hash); } #endif /* HAVE_CDDB */ } else if (options.cdda_add_to_playlist) { cdda_add_to_playlist(&iter_drive, drive->disc.hash); } } void insert_cdda_drive_node(char * device_path) { GtkTreeIter iter_cdda; GtkTreeIter iter_drive; cdda_drive_t * drive = cdda_get_drive_by_device_path(device_path); char str_title[MAXLEN]; char str_sort[16]; if (drive == NULL) { return; } if (drive->disc.n_tracks > 0) { snprintf(str_title, MAXLEN-1, "%s [%s]", _("Unknown disc"), cdda_displayed_device_path(device_path)); } else { snprintf(str_title, MAXLEN-1, "%s [%s]", _("No disc"), cdda_displayed_device_path(device_path)); } snprintf(str_sort, 15, "%d", cdda_get_n(device_path)); gtk_tree_model_get_iter_first(GTK_TREE_MODEL(music_store), &iter_cdda); gtk_tree_store_append(music_store, &iter_drive, &iter_cdda); gtk_tree_store_set(music_store, &iter_drive, MS_COL_NAME, str_title, MS_COL_SORT, str_sort, MS_COL_DATA, drive, -1); if (options.enable_ms_tree_icons) { if (drive->disc.n_tracks > 0) { gtk_tree_store_set(music_store, &iter_drive, MS_COL_ICON, icon_cdda_disc, -1); } else { gtk_tree_store_set(music_store, &iter_drive, MS_COL_ICON, icon_cdda_nodisc, -1); } } if (drive->disc.n_tracks > 0) { update_track_data(drive, iter_drive); } music_store_selection_changed(STORE_TYPE_CDDA); } void remove_cdda_drive_node(char * device_path) { GtkTreeIter iter_cdda; GtkTreeIter iter_drive; cdda_drive_t * drive; int i, found; gtk_tree_model_get_iter_first(GTK_TREE_MODEL(music_store), &iter_cdda); i = found = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &iter_drive, &iter_cdda, i++)) { gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter_drive, MS_COL_DATA, &drive, -1); if (strcmp(drive->device_path, device_path) == 0) { found = 1; break; } } if (found) { store_cdda_remove_record(&iter_drive); } music_store_selection_changed(STORE_TYPE_CDDA); } void refresh_cdda_drive_node(char * device_path) { GtkTreeIter iter_cdda; GtkTreeIter iter_drive; GtkTreeIter iter_tmp; cdda_drive_t * drive; char str_title[MAXLEN]; int i, found; gtk_tree_model_get_iter_first(GTK_TREE_MODEL(music_store), &iter_cdda); i = found = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &iter_drive, &iter_cdda, i++)) { gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter_drive, MS_COL_DATA, &drive, -1); if (strcmp(drive->device_path, device_path) == 0) { found = 1; break; } } if (!found) { return; } if (drive->disc.n_tracks > 0) { snprintf(str_title, MAXLEN-1, "%s [%s]", _("Unknown disc"), cdda_displayed_device_path(device_path)); } else { snprintf(str_title, MAXLEN-1, "%s [%s]", _("No disc"), cdda_displayed_device_path(device_path)); } gtk_tree_store_set(music_store, &iter_drive, MS_COL_NAME, str_title, -1); if (gtk_tree_model_iter_n_children(GTK_TREE_MODEL(music_store), &iter_drive) > 0) { if (options.cdda_remove_from_playlist) { cdda_remove_from_playlist(drive); } while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &iter_tmp, &iter_drive, 0)) { store_cdda_remove_track(&iter_tmp); } } if (options.enable_ms_tree_icons) { if (drive->disc.n_tracks > 0) { gtk_tree_store_set(music_store, &iter_drive, MS_COL_ICON, icon_cdda_disc, -1); } else { gtk_tree_store_set(music_store, &iter_drive, MS_COL_ICON, icon_cdda_nodisc, -1); } } if (drive->disc.n_tracks > 0) { update_track_data(drive, iter_drive); } music_store_selection_changed(STORE_TYPE_CDDA); } void cdda_shutdown(void) { if (options.cdda_remove_from_playlist) { GtkTreeIter iter_cdda; GtkTreeIter iter_drive; cdda_drive_t * drive; int i = 0; gtk_tree_model_get_iter_first(GTK_TREE_MODEL(music_store), &iter_cdda); while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &iter_drive, &iter_cdda, i++)) { gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter_drive, MS_COL_DATA, &drive, -1); if (gtk_tree_model_iter_n_children(GTK_TREE_MODEL(music_store), &iter_drive) > 0) { cdda_remove_from_playlist(drive); } } } cdda_scanner_stop(); } #endif /* HAVE_CDDA */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/cddb_lookup.h0000644000175000001440000000257710657140026014353 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: cddb_lookup.h 739 2007-07-20 19:58:26Z peterszilagyi $ */ #ifndef _CDDB_LOOKUP_H #define _CDDB_LOOKUP_H void cddb_start_query(GtkTreeIter * record_iter, int ntracks, int * frames, int length); void cddb_start_submit(GtkTreeIter * iter_record, int ntracks, int * frames, int length); void cddb_auto_query_cdda(GtkTreeIter * drive_iter, int ntracks, int * frames, int length); void cddb_query_batch(int ntracks, int * frames, int length, char * artist, char * record, int * year, char ** tracks); #endif /* _CDDB_LOOKUP_H */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/cddb_lookup.c0000644000175000001440000011524510742221371014341 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: cddb_lookup.c 981 2008-01-11 20:41:39Z peterszilagyi $ */ #include #ifdef HAVE_CDDB #include #include #include #include #include #ifdef _WIN32 #include #else #include #endif /* _WIN32 */ #include "common.h" #include "utils.h" #include "utils_gui.h" #include "i18n.h" #include "options.h" #include "music_browser.h" #include "store_cdda.h" #include "store_file.h" #include "playlist.h" #include "cdda.h" #include "cddb_lookup.h" extern options_t options; extern GtkWidget * browser_window; extern GtkTreeStore * music_store; extern GtkTreeSelection * music_select; enum { CASE_UP, CASE_DOWN }; enum { CDDB_INIT, CDDB_BUSY, CDDB_SUCCESS, CDDB_ERROR, CDDB_NO_MATCH, CDDB_ABORTED }; enum { CDDB_TYPE_QUERY, CDDB_TYPE_SUBMIT, CDDB_TYPE_SUBMIT_NEW }; typedef struct { AQUALUNG_THREAD_DECLARE(thread_id); AQUALUNG_MUTEX_DECLARE(mutex); int state; int type; int ntracks; int * frames; int record_length; cddb_disc_t ** records; int nrecords; int counter; int aborted; GtkTreeIter iter_record; GtkWidget * progress_win; GtkWidget * progress_label; GtkWidget * progbar; GtkWidget * combo; GtkWidget * artist_entry; GtkWidget * title_entry; GtkWidget * year_spinner; GtkWidget * category_entry; GtkWidget * category_combo; GtkWidget * genre_entry; GtkWidget * ext_entry; GtkWidget * track_list; GtkListStore * track_store; GtkWidget * year_import_button; GtkWidget * title_import_button; int year_imported; int title_imported; } cddb_lookup_t; void cddb_dialog(cddb_lookup_t * data); void cddb_dialog_load_disc(cddb_lookup_t * data, cddb_disc_t * disc); const char * notnull(const char * str) { return str ? str : ""; } cddb_lookup_t * cddb_lookup_new () { cddb_lookup_t * data; if ((data = calloc(1, sizeof(cddb_lookup_t))) == NULL) { fprintf(stderr, "cddb_lookup_new: calloc error\n"); return NULL; } #ifdef _WIN32 data->mutex = g_mutex_new(); #endif /* _WIN32 */ data->state = CDDB_INIT; return data; } void cddb_lookup_set_state(cddb_lookup_t * data, int state) { AQUALUNG_MUTEX_LOCK(data->mutex); data->state = state; AQUALUNG_MUTEX_UNLOCK(data->mutex); } int cddb_lookup_get_state(cddb_lookup_t * data) { int state; AQUALUNG_MUTEX_LOCK(data->mutex); state = data->state; AQUALUNG_MUTEX_UNLOCK(data->mutex); return state; } void cddb_lookup_free(cddb_lookup_t * data) { if (data->records != NULL) { int i; for (i = 0; i < data->nrecords; i++) { if (data->records[i] != NULL) { cddb_disc_destroy(data->records[i]); } } free(data->records); } if (data->frames != NULL) { free(data->frames); } #ifdef _WIN32 g_mutex_free(data->mutex); #endif /* _WIN32 */ free(data); } int cddb_connection_setup(cddb_conn_t ** conn) { if ((*conn = cddb_new()) == NULL) { fprintf(stderr, "cddb_lookup.c: cddb_connection_setup(): cddb_new error\n"); return 1; } cddb_set_server_name(*conn, options.cddb_server); cddb_set_timeout(*conn, options.cddb_timeout); cddb_set_charset(*conn, "UTF-8"); if (options.cddb_local[0] != '\0') { cddb_cache_set_dir(*conn, options.cddb_local); } if (options.cddb_cache_only) { cddb_cache_only(*conn); } if (options.inet_use_proxy) { cddb_http_enable(*conn); cddb_set_server_port(*conn, 80); cddb_http_proxy_enable(*conn); cddb_set_http_proxy_server_name(*conn, options.inet_proxy); cddb_set_http_proxy_server_port(*conn, options.inet_proxy_port); } else { cddb_http_proxy_disable(*conn); if (options.cddb_use_http) { cddb_http_enable(*conn); cddb_set_server_port(*conn, 80); } else { cddb_http_disable(*conn); cddb_set_server_port(*conn, 888); } } return 0; } void cddb_lookup(cddb_lookup_t * data) { cddb_conn_t * conn = NULL; cddb_disc_t * disc = NULL; cddb_track_t * track = NULL; int i; if (cddb_connection_setup(&conn) == 1) { cddb_lookup_set_state(data, CDDB_ERROR); return; } if ((disc = cddb_disc_new()) == NULL) { fprintf(stderr, "cddb_lookup(): cddb_disc_new error\n"); cddb_lookup_set_state(data, CDDB_ERROR); return; } cddb_disc_set_length(disc, data->record_length); for (i = 0; i < data->ntracks; i++) { track = cddb_track_new(); cddb_track_set_frame_offset(track, data->frames[i]); cddb_disc_add_track(disc, track); } data->nrecords = cddb_query(conn, disc); if (data->nrecords <= 0) { cddb_destroy(conn); cddb_disc_destroy(disc); cddb_lookup_set_state(data, (data->nrecords == 0) ? CDDB_NO_MATCH : CDDB_ERROR); return; } cddb_lookup_set_state(data, CDDB_BUSY); if ((data->records = (cddb_disc_t **)calloc(data->nrecords, sizeof(cddb_disc_t *))) == NULL) { fprintf(stderr, "cddb_lookup(): malloc error\n"); cddb_lookup_set_state(data, CDDB_ERROR); return; } for (i = 0; i < data->nrecords; i++) { if (cddb_lookup_get_state(data) == CDDB_ABORTED) { break; } if (i > 0 && !cddb_query_next(conn, disc)) { break; } cddb_read(conn, disc); data->records[i] = cddb_disc_clone(disc); AQUALUNG_MUTEX_LOCK(data->mutex); data->counter++; AQUALUNG_MUTEX_UNLOCK(data->mutex); } cddb_destroy(conn); cddb_disc_destroy(disc); if (cddb_lookup_get_state(data) == CDDB_ABORTED) { cddb_lookup_free(data); return; } cddb_lookup_set_state(data, CDDB_SUCCESS); } static void abort_cb(GtkWidget * widget, gpointer user_data) { cddb_lookup_set_state((cddb_lookup_t *)user_data, CDDB_ABORTED); } void create_query_progress_window(cddb_lookup_t * data) { GtkWidget * vbox; GtkWidget * hbuttonbox; GtkWidget * hseparator; GtkWidget * abort_button; data->progress_win = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(data->progress_win), _("CDDB query")); gtk_window_set_position(GTK_WINDOW(data->progress_win), GTK_WIN_POS_CENTER); gtk_window_resize(GTK_WINDOW(data->progress_win), 330, 120); g_signal_connect(G_OBJECT(data->progress_win), "delete_event", G_CALLBACK(abort_cb), data); gtk_container_set_border_width(GTK_CONTAINER(data->progress_win), 10); vbox = gtk_vbox_new(FALSE, 0); gtk_container_add(GTK_CONTAINER(data->progress_win), vbox); data->progress_label = gtk_label_new(_("Retrieving matches from server...")); gtk_box_pack_start(GTK_BOX(vbox), data->progress_label, FALSE, FALSE, 0); data->progbar = gtk_progress_bar_new(); gtk_progress_bar_set_text(GTK_PROGRESS_BAR(data->progbar), _("Connecting to CDDB server...")); gtk_box_pack_start(GTK_BOX(vbox), data->progbar, FALSE, FALSE, 6); hseparator = gtk_hseparator_new (); gtk_widget_show (hseparator); gtk_box_pack_start (GTK_BOX (vbox), hseparator, FALSE, TRUE, 5); hbuttonbox = gtk_hbutton_box_new(); gtk_box_pack_end(GTK_BOX(vbox), hbuttonbox, FALSE, TRUE, 0); gtk_button_box_set_layout(GTK_BUTTON_BOX(hbuttonbox), GTK_BUTTONBOX_END); abort_button = gui_stock_label_button(_("Abort"), GTK_STOCK_CANCEL); g_signal_connect(G_OBJECT(abort_button), "clicked", G_CALLBACK(abort_cb), data); gtk_container_add(GTK_CONTAINER(hbuttonbox), abort_button); gtk_widget_grab_focus(abort_button); gtk_widget_show_all(data->progress_win); } #ifdef HAVE_CDDA void store_cdda_export_merged(cddb_lookup_t * data, char * artist, char * record, char * genre, int year, char ** tracks) { int i; GtkTreeIter iter; char name[MAXLEN]; cdda_drive_t * drive; for (i = 0; gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &iter, &data->iter_record, i); i++) { gtk_tree_store_set(music_store, &iter, MS_COL_NAME, tracks[i], -1); } gtk_tree_model_get(GTK_TREE_MODEL(music_store), &data->iter_record, MS_COL_DATA, &drive, -1); strncpy(drive->disc.artist_name, artist, MAXLEN-1); strncpy(drive->disc.record_name, record, MAXLEN-1); strncpy(drive->disc.genre, genre, MAXLEN-1); drive->disc.year = year; snprintf(name, MAXLEN-1, "%s: %s", drive->disc.artist_name, drive->disc.record_name); gtk_tree_store_set(music_store, &data->iter_record, MS_COL_NAME, name, -1); music_store_selection_changed(STORE_TYPE_CDDA); } #endif /* HAVE_CDDA */ void cddb_lookup_merge(cddb_lookup_t * data, char * artist, char * record, char * genre, int * year, char ** tracks) { int i, j, y; map_t * map_artist = NULL; map_t * map_record = NULL; map_t * map_genre = NULL; map_t * map_year = NULL; map_t ** map_tracks = NULL; char tmp[MAXLEN]; if ((map_tracks = (map_t **)calloc(data->ntracks, sizeof(map_t *))) == NULL) { fprintf(stderr, "cddb_lookup_merge: calloc error\n"); return; } for (i = 0; i < data->nrecords; i++) { strncpy(tmp, notnull(cddb_disc_get_artist(data->records[i])), MAXLEN-1); if (!is_all_wspace(tmp)) { map_put(&map_artist, tmp); } strncpy(tmp, notnull(cddb_disc_get_title(data->records[i])), MAXLEN-1); if (!is_all_wspace(tmp)) { map_put(&map_record, tmp); } if (genre != NULL) { strncpy(tmp, notnull(cddb_disc_get_genre(data->records[i])), MAXLEN-1); if (!is_all_wspace(tmp)) { map_put(&map_genre, tmp); } } y = cddb_disc_get_year(data->records[i]); if (is_valid_year(y)) { snprintf(tmp, MAXLEN-1, "%d", y); map_put(&map_year, tmp); } for (j = 0; j < data->ntracks; j++) { strncpy(tmp, notnull(cddb_track_get_title(cddb_disc_get_track(data->records[i], j))), MAXLEN-1); if (!is_all_wspace(tmp)) { map_put(map_tracks + j, tmp); } } } if (map_artist) { strncpy(artist, map_get_max(map_artist), MAXLEN-1); } if (map_record) { strncpy(record, map_get_max(map_record), MAXLEN-1); } if (map_genre) { strncpy(genre, map_get_max(map_genre), MAXLEN-1); } if (map_year) { *year = atoi(map_get_max(map_year)); } for (j = 0; j < data->ntracks; j++) { if (map_tracks[j]) { strncpy(tracks[j], map_get_max(map_tracks[j]), MAXLEN-1); map_free(map_tracks[j]); } } map_free(map_artist); map_free(map_record); map_free(map_genre); map_free(map_year); free(map_tracks); } gboolean query_timeout_cb(gpointer user_data) { cddb_lookup_t * data = (cddb_lookup_t *)user_data; int state = cddb_lookup_get_state(data); char text[MAXLEN]; switch (state) { case CDDB_INIT: return TRUE; case CDDB_BUSY: snprintf(text, MAXLEN, "%d / %d", data->counter, data->nrecords); gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(data->progbar), (double)data->counter / data->nrecords); gtk_progress_bar_set_text(GTK_PROGRESS_BAR(data->progbar), text); return TRUE; case CDDB_SUCCESS: gtk_widget_destroy(data->progress_win); cddb_dialog(data); break; case CDDB_ERROR: gtk_widget_destroy(data->progress_win); message_dialog(_("Error"), browser_window, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, NULL, _("An error occurred while attempting " "to connect to the CDDB server.")); break; case CDDB_NO_MATCH: gtk_widget_destroy(data->progress_win); if (data->type == CDDB_TYPE_QUERY) { message_dialog(_("Warning"), browser_window, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, NULL, _("No matching record found.")); } else { data->type = CDDB_TYPE_SUBMIT_NEW; cddb_dialog(data); } break; case CDDB_ABORTED: gtk_widget_destroy(data->progress_win); return FALSE; } cddb_lookup_free(data); return FALSE; } #ifdef HAVE_CDDA gboolean cdda_auto_query_timeout_cb(gpointer user_data) { cddb_lookup_t * data = (cddb_lookup_t *)user_data; int state = cddb_lookup_get_state(data); if (state == CDDB_INIT || state == CDDB_BUSY) { return TRUE; } if (state == CDDB_SUCCESS) { char artist[MAXLEN]; char record[MAXLEN]; char genre[MAXLEN]; int year = 0; char ** tracks; int i; artist[0] = '\0'; record[0] = '\0'; genre[0] = '\0'; if ((tracks = calloc(data->ntracks, sizeof(char *))) == NULL) { fprintf(stderr, "cdda_auto_query_timeout_cb(): calloc error\n"); return FALSE; } for (i = 0; i < data->ntracks; i++) { if ((tracks[i] = calloc(1, MAXLEN * sizeof(char))) == NULL) { fprintf(stderr, "cdda_auto_query_timeout_cb(): calloc error\n"); return FALSE; } } cddb_lookup_merge(data, artist, record, genre, &year, tracks); store_cdda_export_merged(data, artist, record, genre, year, tracks); for (i = 0; i < data->ntracks; i++) { free(tracks[i]); } free(tracks); } if (options.cdda_add_to_playlist) { cdda_drive_t * drive; gtk_tree_model_get(GTK_TREE_MODEL(music_store), &data->iter_record, MS_COL_DATA, &drive, -1); cdda_add_to_playlist(&data->iter_record, drive->disc.hash); } cddb_lookup_free(data); return FALSE; } #endif /* HAVE_CDDA */ static void add_to_comments(cddb_lookup_t * data, GtkWidget * entry) { record_data_t * record_data; gtk_tree_model_get(GTK_TREE_MODEL(music_store), &data->iter_record, MS_COL_DATA, &record_data, -1); if (record_data->comment != NULL && record_data->comment[0] != '\0') { char comment[MAXLEN]; snprintf(comment, MAXLEN-1, "%s\n%s", record_data->comment, gtk_entry_get_text(GTK_ENTRY(entry))); free_strdup(&record_data->comment, comment); } else { free_strdup(&record_data->comment, gtk_entry_get_text(GTK_ENTRY(entry))); } music_store_mark_changed(&data->iter_record); } static void add_category_to_comments(GtkWidget * widget, gpointer user_data) { cddb_lookup_t * data = (cddb_lookup_t *)user_data; add_to_comments(data, data->category_entry); } static void add_genre_to_comments(GtkWidget * widget, gpointer user_data) { cddb_lookup_t * data = (cddb_lookup_t *)user_data; add_to_comments(data, data->genre_entry); } static void add_ext_to_comments(GtkWidget * widget, gpointer user_data) { cddb_lookup_t * data = (cddb_lookup_t *)user_data; add_to_comments(data, data->ext_entry); } static void import_as_artist(GtkWidget * widget, gpointer user_data) { GtkTreeIter parent; GtkTreePath * path; cddb_lookup_t * data = (cddb_lookup_t *)user_data; path = gtk_tree_model_get_path(GTK_TREE_MODEL(music_store), &data->iter_record); gtk_tree_path_up(path); gtk_tree_model_get_iter(GTK_TREE_MODEL(music_store), &parent, path); gtk_tree_path_free(path); gtk_tree_store_set(music_store, &parent, MS_COL_NAME, gtk_entry_get_text(GTK_ENTRY(data->artist_entry)), -1); music_store_mark_changed(&parent); } static void import_as_title(GtkWidget * widget, gpointer user_data) { cddb_lookup_t * data = (cddb_lookup_t *)user_data; if (data->title_imported) { gtk_tree_store_set(music_store, &data->iter_record, MS_COL_SORT, gtk_entry_get_text(GTK_ENTRY(data->title_entry)), -1); } else { gtk_tree_store_set(music_store, &data->iter_record, MS_COL_NAME, gtk_entry_get_text(GTK_ENTRY(data->title_entry)), -1); data->title_imported = 1; gtk_button_set_label(GTK_BUTTON(data->title_import_button), _("Import as Sort Key")); } music_store_mark_changed(&data->iter_record); } static void import_as_year(GtkWidget * widget, gpointer user_data) { cddb_lookup_t * data = (cddb_lookup_t *)user_data; int year = gtk_spin_button_get_value(GTK_SPIN_BUTTON(data->year_spinner)); if (data->year_imported) { char buf[16]; snprintf(buf, 15, "%d", year); gtk_tree_store_set(music_store, &data->iter_record, MS_COL_SORT, buf, -1); } else { record_data_t * record_data; gtk_tree_model_get(GTK_TREE_MODEL(music_store), &data->iter_record, MS_COL_DATA, &record_data, -1); record_data->year = year; data->year_imported = 1; gtk_button_set_label(GTK_BUTTON(data->year_import_button), _("Import as Sort Key")); } music_store_mark_changed(&data->iter_record); } gboolean title_entry_focused(GtkWidget * widget, GdkEventFocus * event, gpointer user_data) { cddb_lookup_t * data = (cddb_lookup_t *)user_data; data->title_imported = 0; gtk_button_set_label(GTK_BUTTON(data->title_import_button), _("Import as Title")); return FALSE; } gboolean year_spinner_focused(GtkWidget * widget, GdkEventFocus * event, gpointer user_data) { cddb_lookup_t * data = (cddb_lookup_t *)user_data; data->year_imported = 0; gtk_button_set_label(GTK_BUTTON(data->year_import_button), _("Import as Year")); return FALSE; } static void changed_combo(GtkWidget * widget, gpointer * user_data) { cddb_lookup_t * data = (cddb_lookup_t *)user_data; int i = gtk_combo_box_get_active(GTK_COMBO_BOX(data->combo)); if (i >= 0 && i < data->nrecords) { cddb_dialog_load_disc(data, data->records[i]); } if (data->type == CDDB_TYPE_QUERY && iter_get_store_type(&data->iter_record) == STORE_TYPE_FILE) { title_entry_focused(data->title_entry, NULL, user_data); year_spinner_focused(data->year_spinner, NULL, user_data); } } static void cell_edited_callback(GtkCellRendererText * cell, gchar * path, gchar * text, gpointer user_data) { cddb_lookup_t * data = (cddb_lookup_t *)user_data; GtkTreeIter iter; if (gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(data->track_store), &iter, path)) { gtk_list_store_set(data->track_store, &iter, 0, text, -1); } } gboolean create_cddb_write_error_dialog(gpointer data) { message_dialog(_("Error"), browser_window, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, NULL, (char *)data); return FALSE; } int create_cddb_write_warn_dialog(char * text) { int ret = message_dialog(_("Warning"), browser_window, GTK_MESSAGE_WARNING, GTK_BUTTONS_YES_NO, NULL, text); return (ret != GTK_RESPONSE_YES); } static int check_case(char * text, int _case) { char * str; char * p; int has = 0; int ret = 0; for (p = text; *p; p = g_utf8_next_char(p)) { gunichar ch = g_utf8_get_char(p); if (g_unichar_islower(ch) || g_unichar_isupper(ch)) { has = 1; break; } } if (!has) { return 1; } switch (_case) { case CASE_UP: str = g_utf8_strup(text, -1); ret = strcmp(str, text); g_free(str); break; case CASE_DOWN: str = g_utf8_strdown(text, -1); ret = strcmp(str, text); g_free(str); break; } return ret; } int cddb_submit_check(cddb_lookup_t * data) { GtkTreeIter iter_trlist; char * artist; char * title; char * genre; char * ext; int category; int year; int i; artist = (char *)gtk_entry_get_text(GTK_ENTRY(data->artist_entry)); if (is_all_wspace(artist)) { gtk_widget_grab_focus(data->artist_entry); return 1; } if (!check_case(artist, CASE_DOWN)) { if (create_cddb_write_warn_dialog(_("Artist appears to be in all lowercase.\n" "Do you want to proceed?"))) { gtk_widget_grab_focus(data->artist_entry); return 1; } } if (!check_case(artist, CASE_UP)) { if (create_cddb_write_warn_dialog(_("Artist appears to be in all uppercase.\n" "Do you want to proceed?"))) { gtk_widget_grab_focus(data->artist_entry); return 1; } } title = (char *)gtk_entry_get_text(GTK_ENTRY(data->title_entry)); if (is_all_wspace(title)) { gtk_widget_grab_focus(data->title_entry); return 1; } if (!check_case(title, CASE_DOWN)) { if (create_cddb_write_warn_dialog(_("Title appears to be in all lowercase.\n" "Do you want to proceed?"))) { gtk_widget_grab_focus(data->title_entry); return 1; } } if (!check_case(title, CASE_UP)) { if (create_cddb_write_warn_dialog(_("Title appears to be in all uppercase.\n" "Do you want to proceed?"))) { gtk_widget_grab_focus(data->title_entry); return 1; } } year = gtk_spin_button_get_value(GTK_SPIN_BUTTON(data->year_spinner)); if (year == YEAR_MIN) { if (create_cddb_write_warn_dialog(_("It is very likely that the year is wrong.\n" "Do you want to proceed?"))) { gtk_widget_grab_focus(data->year_spinner); return 1; } } if (data->type == CDDB_TYPE_SUBMIT_NEW) { category = gtk_combo_box_get_active(GTK_COMBO_BOX(data->category_combo)); if (category == 0) { gtk_widget_grab_focus(data->category_combo); return 1; } } genre = (char *)gtk_entry_get_text(GTK_ENTRY(data->genre_entry)); if (genre[0] != '\0' && is_all_wspace(genre)) { gtk_widget_grab_focus(data->genre_entry); return 1; } ext = (char *)gtk_entry_get_text(GTK_ENTRY(data->ext_entry)); if (ext[0] != '\0' && is_all_wspace(ext)) { gtk_widget_grab_focus(data->ext_entry); return 1; } for (i = 0; gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(data->track_store), &iter_trlist, NULL, i); i++) { char * name; gtk_tree_model_get(GTK_TREE_MODEL(data->track_store), &iter_trlist, 0, &name, -1); if (is_all_wspace(name)) { gtk_tree_selection_select_iter(gtk_tree_view_get_selection(GTK_TREE_VIEW(data->track_list)), &iter_trlist); return 1; } g_free(name); } return 0; } void cddb_submit(cddb_lookup_t * data, int n) { GtkTreeIter iter_trlist; cddb_conn_t * conn = NULL; cddb_disc_t * disc = NULL; int i; if (cddb_connection_setup(&conn) == 1) { return; } if (!cddb_set_email_address(conn, options.cddb_email)) { create_cddb_write_error_dialog(_("The email address provided for submission is invalid.")); cddb_destroy(conn); return; } cddb_http_enable(conn); cddb_set_server_port(conn, 80); if (n < 0) { cddb_track_t * track = NULL; if ((disc = cddb_disc_new()) == NULL) { fprintf(stderr, "cddb_submit: cddb_disc_new error\n"); cddb_destroy(conn); return; } for (i = 0; i < data->ntracks; i++) { track = cddb_track_new(); cddb_track_set_frame_offset(track, data->frames[i]); cddb_disc_add_track(disc, track); } cddb_disc_set_length(disc, data->record_length); cddb_disc_set_category(disc, gtk_combo_box_get_active(GTK_COMBO_BOX(data->category_combo)) - 1); if (cddb_disc_calc_discid(disc) == 0) { fprintf(stderr, "cddb_submit: cddb_disc_calc_discid error\n"); cddb_disc_destroy(disc); cddb_destroy(conn); return; } } else { disc = data->records[n]; #ifdef LIBCDDB_REVISION cddb_disc_set_revision(disc, cddb_disc_get_revision(disc) + 1); #endif /* LIBCDDB_REVISION */ } for (i = 0; gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(data->track_store), &iter_trlist, NULL, i); i++) { char * name; gtk_tree_model_get(GTK_TREE_MODEL(data->track_store), &iter_trlist, 0, &name, -1); cddb_track_set_title(cddb_disc_get_track(disc, i), name); g_free(name); } cddb_disc_set_artist(disc, gtk_entry_get_text(GTK_ENTRY(data->artist_entry))); cddb_disc_set_title(disc, gtk_entry_get_text(GTK_ENTRY(data->title_entry))); cddb_disc_set_year(disc, gtk_spin_button_get_value(GTK_SPIN_BUTTON(data->year_spinner))); cddb_disc_set_genre(disc, gtk_entry_get_text(GTK_ENTRY(data->genre_entry))); cddb_disc_set_ext_data(disc, gtk_entry_get_text(GTK_ENTRY(data->ext_entry))); if (!cddb_write(conn, disc)) { create_cddb_write_error_dialog(_("An error occurred while submitting the record to the CDDB server.")); } cddb_destroy(conn); if (n < 0) { cddb_disc_destroy(disc); } } void cddb_dialog_load_disc(cddb_lookup_t * data, cddb_disc_t * disc) { GtkTreeIter iter; int i; gtk_entry_set_text(GTK_ENTRY(data->artist_entry), notnull(cddb_disc_get_artist(disc))); gtk_entry_set_text(GTK_ENTRY(data->title_entry), notnull(cddb_disc_get_title(disc))); gtk_entry_set_text(GTK_ENTRY(data->category_entry), notnull(cddb_disc_get_category_str(disc))); gtk_entry_set_text(GTK_ENTRY(data->genre_entry), notnull(cddb_disc_get_genre(disc))); gtk_entry_set_text(GTK_ENTRY(data->ext_entry), notnull(cddb_disc_get_ext_data(disc))); gtk_spin_button_set_value(GTK_SPIN_BUTTON(data->year_spinner), cddb_disc_get_year(disc)); gtk_list_store_clear(GTK_LIST_STORE(data->track_store)); for (i = 0; i < data->ntracks; i++) { gtk_list_store_append(data->track_store, &iter); gtk_list_store_set(data->track_store, &iter, 0, notnull(cddb_track_get_title(cddb_disc_get_track(disc, i))), -1); } } void store_load_tracklist(cddb_lookup_t * data) { GtkTreeIter iter; GtkTreeIter iter_trlist; int i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &iter, &data->iter_record, i++)) { char * name; gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter, MS_COL_NAME, &name, -1); gtk_list_store_append(data->track_store, &iter_trlist); gtk_list_store_set(data->track_store, &iter_trlist, 0, name, -1); g_free(name); } } void cddb_dialog_load_store_file(cddb_lookup_t * data) { GtkTreeIter iter_artist; record_data_t * record_data; char * str; store_load_tracklist(data); gtk_tree_model_iter_parent(GTK_TREE_MODEL(music_store), &iter_artist, &data->iter_record); gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter_artist, MS_COL_NAME, &str, -1); gtk_entry_set_text(GTK_ENTRY(data->artist_entry), str); g_free(str); gtk_tree_model_get(GTK_TREE_MODEL(music_store), &data->iter_record, MS_COL_NAME, &str, -1); gtk_entry_set_text(GTK_ENTRY(data->title_entry), str); g_free(str); gtk_tree_model_get(GTK_TREE_MODEL(music_store), &data->iter_record, MS_COL_DATA, &record_data, -1); gtk_spin_button_set_value(GTK_SPIN_BUTTON(data->year_spinner), record_data->year); } #ifdef HAVE_CDDA void cddb_dialog_load_store_cdda(cddb_lookup_t * data) { store_load_tracklist(data); cdda_drive_t * drive; gtk_tree_model_get(GTK_TREE_MODEL(music_store), &data->iter_record, MS_COL_DATA, &drive, -1); gtk_entry_set_text(GTK_ENTRY(data->artist_entry), drive->disc.artist_name); gtk_entry_set_text(GTK_ENTRY(data->title_entry), drive->disc.record_name); gtk_entry_set_text(GTK_ENTRY(data->genre_entry), drive->disc.genre); gtk_spin_button_set_value(GTK_SPIN_BUTTON(data->year_spinner), drive->disc.year); } #endif /* HAVE_CDDA */ void export_tracklist(cddb_lookup_t * data) { int i; GtkTreeIter iter; GtkTreeIter iter_trlist; for (i = 0; gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &iter, &data->iter_record, i); i++) { if (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(data->track_store), &iter_trlist, NULL, i)) { char * name; gtk_tree_model_get(GTK_TREE_MODEL(data->track_store), &iter_trlist, 0, &name, -1); gtk_tree_store_set(music_store, &iter, MS_COL_NAME, name, -1); g_free(name); } } } void store_file_export(cddb_lookup_t * data) { export_tracklist(data); music_store_mark_changed(&data->iter_record); } #ifdef HAVE_CDDA void store_cdda_export(cddb_lookup_t * data) { char name[MAXLEN]; cdda_drive_t * drive; export_tracklist(data); gtk_tree_model_get(GTK_TREE_MODEL(music_store), &data->iter_record, MS_COL_DATA, &drive, -1); strncpy(drive->disc.artist_name, gtk_entry_get_text(GTK_ENTRY(data->artist_entry)), MAXLEN-1); strncpy(drive->disc.record_name, gtk_entry_get_text(GTK_ENTRY(data->title_entry)), MAXLEN-1); strncpy(drive->disc.genre, gtk_entry_get_text(GTK_ENTRY(data->genre_entry)), MAXLEN-1); drive->disc.year = gtk_spin_button_get_value(GTK_SPIN_BUTTON(data->year_spinner)); snprintf(name, MAXLEN-1, "%s: %s", drive->disc.artist_name, drive->disc.record_name); gtk_tree_store_set(music_store, &data->iter_record, MS_COL_NAME, name, -1); } #endif /* HAVE_CDDA */ void cddb_dialog(cddb_lookup_t * data) { GtkWidget * dialog; GtkWidget * table; GtkWidget * hbox; GtkWidget * label; GtkWidget * button; GtkWidget * viewport; GtkWidget * scrollwin; GtkCellRenderer * renderer; GtkTreeViewColumn * column; int i; char text[MAXLEN]; dialog = gtk_dialog_new_with_buttons(NULL, GTK_WINDOW(browser_window), GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL); gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER); gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT); switch (data->type) { case CDDB_TYPE_QUERY: gtk_window_set_title(GTK_WINDOW(dialog), _("CDDB query")); break; case CDDB_TYPE_SUBMIT: gtk_window_set_title(GTK_WINDOW(dialog), _("Correct existing record")); break; case CDDB_TYPE_SUBMIT_NEW: gtk_window_set_title(GTK_WINDOW(dialog), _("Submit new record")); break; } table = gtk_table_new(8, 3, FALSE); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), table, FALSE, FALSE, 2); if (data->type != CDDB_TYPE_SUBMIT_NEW) { hbox = gtk_hbox_new(FALSE, 0); gtk_table_attach(GTK_TABLE(table), hbox, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 5, 3); label = gtk_label_new(_("Matches:")); gtk_box_pack_end(GTK_BOX(hbox), label, FALSE, FALSE, 2); data->combo = gtk_combo_box_new_text(); for (i = 0; i < data->nrecords; i++) { snprintf(text, MAXLEN, "%d. %s: %s [%x] ", i + 1, notnull(cddb_disc_get_artist(data->records[i])), notnull(cddb_disc_get_title(data->records[i])), cddb_disc_get_discid(data->records[i])); gtk_combo_box_append_text(GTK_COMBO_BOX(data->combo), text); } gtk_combo_box_set_active(GTK_COMBO_BOX(data->combo), 0); g_signal_connect(data->combo, "changed", G_CALLBACK(changed_combo), data); gtk_table_attach(GTK_TABLE(table), data->combo, 1, 3, 0, 1, GTK_FILL, GTK_FILL, 5, 3); } hbox = gtk_hbox_new(FALSE, 0); gtk_table_attach(GTK_TABLE(table), hbox, 0, 1, 1, 2, GTK_FILL, GTK_FILL, 5, 3); label = gtk_label_new(_("Artist:")); gtk_box_pack_end(GTK_BOX(hbox), label, FALSE, FALSE, 2); data->artist_entry = gtk_entry_new(); gtk_table_attach(GTK_TABLE(table), data->artist_entry, 1, 2, 1, 2, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 5, 3); hbox = gtk_hbox_new(FALSE, 0); gtk_table_attach(GTK_TABLE(table), hbox, 0, 1, 2, 3, GTK_FILL, GTK_FILL, 5, 3); label = gtk_label_new(_("Title:")); gtk_box_pack_end(GTK_BOX(hbox), label, FALSE, FALSE, 2); data->title_entry = gtk_entry_new(); gtk_table_attach(GTK_TABLE(table), data->title_entry, 1, 2, 2, 3, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 5, 3); hbox = gtk_hbox_new(FALSE, 0); gtk_table_attach(GTK_TABLE(table), hbox, 0, 1, 3, 4, GTK_FILL, GTK_FILL, 5, 3); label = gtk_label_new(_("Year:")); gtk_box_pack_end(GTK_BOX(hbox), label, FALSE, FALSE, 2); data->year_spinner = gtk_spin_button_new_with_range(YEAR_MIN, YEAR_MAX, 1); gtk_table_attach(GTK_TABLE(table), data->year_spinner, 1, 2, 3, 4, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 5, 3); hbox = gtk_hbox_new(FALSE, 0); gtk_table_attach(GTK_TABLE(table), hbox, 0, 1, 4, 5, GTK_FILL, GTK_FILL, 5, 3); label = gtk_label_new(_("Category:")); gtk_box_pack_end(GTK_BOX(hbox), label, FALSE, FALSE, 2); if (data->type != CDDB_TYPE_SUBMIT_NEW) { data->category_entry = gtk_entry_new(); gtk_entry_set_editable(GTK_ENTRY(data->category_entry), FALSE); gtk_table_attach(GTK_TABLE(table), data->category_entry, 1, 2, 4, 5, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 5, 3); } else { data->category_combo = gtk_combo_box_new_text(); gtk_combo_box_append_text(GTK_COMBO_BOX(data->category_combo), _("(choose a category)")); gtk_combo_box_append_text(GTK_COMBO_BOX(data->category_combo), "data"); gtk_combo_box_append_text(GTK_COMBO_BOX(data->category_combo), "folk"); gtk_combo_box_append_text(GTK_COMBO_BOX(data->category_combo), "jazz"); gtk_combo_box_append_text(GTK_COMBO_BOX(data->category_combo), "misc"); gtk_combo_box_append_text(GTK_COMBO_BOX(data->category_combo), "rock"); gtk_combo_box_append_text(GTK_COMBO_BOX(data->category_combo), "country"); gtk_combo_box_append_text(GTK_COMBO_BOX(data->category_combo), "blues"); gtk_combo_box_append_text(GTK_COMBO_BOX(data->category_combo), "newage"); gtk_combo_box_append_text(GTK_COMBO_BOX(data->category_combo), "reagge"); gtk_combo_box_append_text(GTK_COMBO_BOX(data->category_combo), "classical"); gtk_combo_box_append_text(GTK_COMBO_BOX(data->category_combo), "soundtrack"); gtk_combo_box_set_active(GTK_COMBO_BOX(data->category_combo), 0); gtk_table_attach(GTK_TABLE(table), data->category_combo, 1, 2, 4, 5, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 5, 3); } hbox = gtk_hbox_new(FALSE, 0); gtk_table_attach(GTK_TABLE(table), hbox, 0, 1, 5, 6, GTK_FILL, GTK_FILL, 5, 3); label = gtk_label_new(_("Genre:")); gtk_box_pack_end(GTK_BOX(hbox), label, FALSE, FALSE, 2); data->genre_entry = gtk_entry_new(); gtk_table_attach(GTK_TABLE(table), data->genre_entry, 1, 2, 5, 6, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 5, 3); hbox = gtk_hbox_new(FALSE, 0); gtk_table_attach(GTK_TABLE(table), hbox, 0, 1, 6, 7, GTK_FILL, GTK_FILL, 5, 3); label = gtk_label_new(_("Extended data:")); gtk_box_pack_end(GTK_BOX(hbox), label, FALSE, FALSE, 2); data->ext_entry = gtk_entry_new(); gtk_table_attach(GTK_TABLE(table), data->ext_entry, 1, 2, 6, 7, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 5, 3); if (data->type == CDDB_TYPE_QUERY && iter_get_store_type(&data->iter_record) == STORE_TYPE_FILE) { g_signal_connect(G_OBJECT(data->title_entry), "focus-in-event", G_CALLBACK(title_entry_focused), data); g_signal_connect(G_OBJECT(data->year_spinner), "focus-in-event", G_CALLBACK(year_spinner_focused), data); button = gtk_button_new_with_label(_("Import as Artist")); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(import_as_artist), data); gtk_table_attach(GTK_TABLE(table), button, 2, 3, 1, 2, GTK_FILL, GTK_FILL, 5, 3); data->title_import_button = gtk_button_new_with_label(_("Import as Title")); g_signal_connect(G_OBJECT(data->title_import_button), "clicked", G_CALLBACK(import_as_title), data); gtk_table_attach(GTK_TABLE(table), data->title_import_button, 2, 3, 2, 3, GTK_FILL, GTK_FILL, 5, 3); data->year_import_button = gtk_button_new_with_label(_("Import as Year")); g_signal_connect(G_OBJECT(data->year_import_button), "clicked", G_CALLBACK(import_as_year), data); gtk_table_attach(GTK_TABLE(table), data->year_import_button, 2, 3, 3, 4, GTK_FILL, GTK_FILL, 5, 3); button = gtk_button_new_with_label(_("Add to Comments")); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(add_category_to_comments), data); gtk_table_attach(GTK_TABLE(table), button, 2, 3, 4, 5, GTK_FILL, GTK_FILL, 5, 3); button = gtk_button_new_with_label(_("Add to Comments")); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(add_genre_to_comments), data); gtk_table_attach(GTK_TABLE(table), button, 2, 3, 5, 6, GTK_FILL, GTK_FILL, 5, 3); button = gtk_button_new_with_label(_("Add to Comments")); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(add_ext_to_comments), data); gtk_table_attach(GTK_TABLE(table), button, 2, 3, 6, 7, GTK_FILL, GTK_FILL, 5, 3); } data->track_store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_BOOLEAN); data->track_list = gtk_tree_view_new_with_model(GTK_TREE_MODEL(data->track_store)); renderer = gtk_cell_renderer_text_new(); g_object_set(renderer, "editable", TRUE, NULL); g_signal_connect(renderer, "edited", (GCallback)cell_edited_callback, data); column = gtk_tree_view_column_new_with_attributes(_("Tracks"), renderer, "text", 0, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(data->track_list), column); gtk_tree_view_set_reorderable(GTK_TREE_VIEW(data->track_list), FALSE); viewport = gtk_viewport_new(NULL, NULL); scrollwin = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_widget_set_size_request(scrollwin, -1, 200); gtk_table_attach(GTK_TABLE(table), viewport, 0, 3, 7, 8, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 5, 3); gtk_container_add(GTK_CONTAINER(viewport), scrollwin); gtk_container_add(GTK_CONTAINER(scrollwin), data->track_list); gtk_widget_show_all(dialog); if (data->type != CDDB_TYPE_SUBMIT_NEW) { cddb_dialog_load_disc(data, data->records[0]); } else { if (iter_get_store_type(&data->iter_record) == STORE_TYPE_FILE) { cddb_dialog_load_store_file(data); } else { #ifdef HAVE_CDDA cddb_dialog_load_store_cdda(data); #endif /* HAVE_CDDA */ } } display: if (aqualung_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { if (data->type == CDDB_TYPE_SUBMIT || data->type == CDDB_TYPE_SUBMIT_NEW) { if (cddb_submit_check(data)) { goto display; } } if (data->type == CDDB_TYPE_SUBMIT) { cddb_submit(data, gtk_combo_box_get_active(GTK_COMBO_BOX(data->combo))); } if (data->type == CDDB_TYPE_SUBMIT_NEW) { cddb_submit(data, -1); } if (data->type == CDDB_TYPE_QUERY) { if (iter_get_store_type(&data->iter_record) == STORE_TYPE_FILE) { store_file_export(data); } else { #ifdef HAVE_CDDA store_cdda_export(data); #endif /* HAVE_CDDA */ } } } gtk_widget_destroy(dialog); } void * cddb_lookup_thread(void * arg) { AQUALUNG_THREAD_DETACH(); cddb_lookup((cddb_lookup_t *)arg); return NULL; } void cddb_start_lookup_thread(GtkTreeIter * iter_record, int type, int progress, int ntracks, int * frames, int length, gboolean (*timeout_cb)(gpointer)) { cddb_lookup_t * data; if ((data = cddb_lookup_new()) == NULL) { return; } data->iter_record = *iter_record; data->type = type; data->ntracks = ntracks; data->frames = frames; data->record_length = length; AQUALUNG_THREAD_CREATE(data->thread_id, NULL, cddb_lookup_thread, data); if (progress) { create_query_progress_window(data); } aqualung_timeout_add(100, timeout_cb, data); } void cddb_start_query(GtkTreeIter * iter_record, int ntracks, int * frames, int length) { cddb_start_lookup_thread(iter_record, CDDB_TYPE_QUERY, 1, ntracks, frames, length, query_timeout_cb); } void cddb_start_submit(GtkTreeIter * iter_record, int ntracks, int * frames, int length) { if (options.cddb_email[0] == '\0') { create_cddb_write_error_dialog(_("You have to provide an email address for CDDB submission.")); return; } cddb_start_lookup_thread(iter_record, CDDB_TYPE_SUBMIT, 1, ntracks, frames, length, query_timeout_cb); } #ifdef HAVE_CDDA void cddb_auto_query_cdda(GtkTreeIter * drive_iter, int ntracks, int * frames, int length) { cddb_start_lookup_thread(drive_iter, CDDB_TYPE_QUERY, 0, ntracks, frames, length, cdda_auto_query_timeout_cb); } #endif /* HAVE_CDDA */ void cddb_query_batch(int ntracks, int * frames, int length, char * artist, char * record, int * year, char ** tracks) { cddb_lookup_t * data; if ((data = cddb_lookup_new()) == NULL) { return; } data->type = CDDB_TYPE_QUERY; data->ntracks = ntracks; data->frames = frames; data->record_length = length; cddb_lookup(data); cddb_lookup_merge(data, artist, record, NULL/*genre*/, year, tracks); cddb_lookup_free(data); } #endif /* HAVE_CDDB */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/cd_ripper.h0000644000175000001440000000242110731047243014021 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: cd_ripper.h 928 2007-12-14 11:46:36Z peterszilagyi $ */ #ifndef _CD_RIPPER_H #define _CD_RIPPER_H #include #if defined(HAVE_CDDA) && (defined(HAVE_SNDFILE) || defined(HAVE_FLAC) || defined(HAVE_VORBISENC) || defined(HAVE_LAME)) #define HAVE_CD_RIPPER #include #include "cdda.h" void cd_ripper(cdda_drive_t * drive, GtkTreeIter * iter); #endif /* HAVE_CDDA && ... */ #endif /* _CD_RIPPER_H */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/cd_ripper.c0000644000175000001440000012533211243310700014011 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: cd_ripper.c 1067 2009-07-24 09:35:15Z peterszilagyi $ */ #include #include #include #include #include #ifdef _WIN32 #include #else #include #endif /* _WIN32 */ #include "common.h" #include "utils.h" #include "utils_gui.h" #include "rb.h" #include "cover.h" #include "decoder/file_decoder.h" #include "decoder/dec_cdda.h" #include "encoder/file_encoder.h" #include "encoder/enc_lame.h" #include "gui_main.h" #include "music_browser.h" #include "store_file.h" #include "options.h" #include "i18n.h" #include "cdda.h" #include "metadata.h" #include "cd_ripper.h" #ifdef HAVE_CD_RIPPER #define BUFSIZE 588 extern options_t options; extern GtkWidget * browser_window; extern GtkTreeStore * music_store; extern GdkPixbuf * icon_artist; extern GdkPixbuf * icon_record; extern GdkPixbuf * icon_track; GtkListStore * ripper_source_store; GtkWidget * ripper_dialog; GtkWidget * ripper_artist_entry; GtkWidget * ripper_album_entry; GtkWidget * ripper_year_spinner; GtkWidget * ripper_genre_entry; GtkWidget * ripper_destdir_entry; GtkWidget * ripper_deststore_combo; GtkWidget * ripper_format_combo; GtkWidget * ripper_bitrate_scale; GtkWidget * ripper_bitrate_label; GtkWidget * ripper_bitrate_value_label; GtkWidget * ripper_vbr_check; GtkWidget * ripper_meta_check; GtkWidget * ripper_overlap_check; GtkWidget * ripper_verify_check; GtkWidget * ripper_neverskip_check; GtkWidget * ripper_maxretries_spinner; GtkWidget * ripper_maxretries_label; GtkListStore * ripper_prog_store; GtkWidget * ripper_prog_window; GtkWidget * ripper_cancel_button; GtkWidget * ripper_close_when_ready_check; GtkWidget * ripper_hbox; int ripper_prog_window_visible; AQUALUNG_THREAD_DECLARE(ripper_thread_id) int ripper_thread_busy; int ripper_format; int ripper_bitrate; int ripper_vbr; int ripper_meta; char ripper_artist[MAXLEN]; char ripper_album[MAXLEN]; char ripper_genre[MAXLEN]; int ripper_year; int ripper_write_to_store; GtkTreeIter ripper_dest_store; GtkTreeIter ripper_dest_artist; GtkTreeIter ripper_dest_record; int ripper_paranoia_mode; int ripper_paranoia_maxretries; int total_sectors; char destdir[MAXLEN]; GtkWidget * create_notebook_page(GtkWidget * nb, char * title) { GtkWidget * vbox = gtk_vbox_new(FALSE, 0); gtk_container_set_border_width(GTK_CONTAINER(vbox), 5); gtk_notebook_append_page(GTK_NOTEBOOK(nb), vbox, gtk_label_new(title)); return vbox; } GtkWidget * create_frame_on_page(GtkWidget * vbox, char * title) { GtkWidget * vbox1; GtkWidget * frame = gtk_frame_new(title); gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 5); vbox1 = gtk_vbox_new(FALSE, 0); gtk_container_add(GTK_CONTAINER(frame), vbox1); return vbox1; } void ripper_source_store_make(GtkTreeIter * record_iter) { GtkTreeIter track_iter; GtkTreeIter iter; int n = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &track_iter, record_iter, n++)) { char * track_name; gtk_tree_model_get(GTK_TREE_MODEL(music_store), &track_iter, MS_COL_NAME, &track_name, -1); gtk_list_store_append(ripper_source_store, &iter); gtk_list_store_set(ripper_source_store, &iter, 0, TRUE, /* rip all tracks by default */ 1, n, 2, track_name, -1); g_free(track_name); } } void ripper_source_write_back(GtkTreeIter * record_iter, char * artist, char * record, char * genre, int year) { GtkTreeIter track_iter; GtkTreeIter iter; int n = 0; cdda_drive_t * drive; cdda_disc_t * disc; char * title; char tmp[MAXLEN]; gtk_tree_model_get(GTK_TREE_MODEL(music_store), record_iter, MS_COL_DATA, &drive, -1); disc = &drive->disc; strncpy(disc->artist_name, artist, MAXLEN-1); strncpy(disc->record_name, record, MAXLEN-1); strncpy(disc->genre, genre, MAXLEN-1); disc->year = year; snprintf(tmp, MAXLEN-1, "%s: %s", artist, record); gtk_tree_store_set(music_store, record_iter, MS_COL_NAME, tmp, -1); while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &track_iter, record_iter, n)) { gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(ripper_source_store), &iter, NULL, n); gtk_tree_model_get(GTK_TREE_MODEL(ripper_source_store), &iter, 2, &title, -1); gtk_tree_store_set(music_store, &track_iter, MS_COL_NAME, title, -1); g_free(title); ++n; } music_store_selection_changed(STORE_TYPE_CDDA); } void ripper_cell_edited_cb(GtkCellRendererText * cell, gchar * path, gchar * text, gpointer data) { GtkTreeIter iter; if (gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(ripper_source_store), &iter, path)) { gtk_list_store_set(ripper_source_store, &iter, 2, text, -1); } } void ripper_cell_toggled_cb(GtkCellRendererToggle * cell, gchar * path, gpointer data) { GtkTreeIter iter; if (gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(ripper_source_store), &iter, path)) { gboolean b; gtk_tree_model_get(GTK_TREE_MODEL(ripper_source_store), &iter, 0, &b, -1); gtk_list_store_set(ripper_source_store, &iter, 0, !b, -1); } } void ripper_set_all_cb(GtkWidget * widget, gpointer data) { gboolean b = (gboolean)GPOINTER_TO_INT(data); GtkTreeIter iter; int n = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(ripper_source_store), &iter, NULL, n++)) { gtk_list_store_set(ripper_source_store, &iter, 0, b, -1); } } void ripper_destdir_browse_cb(GtkButton * button, gpointer data) { file_chooser_with_entry(_("Please select the directory for ripped files."), ripper_dialog, GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, FILE_CHOOSER_FILTER_NONE, (GtkWidget *)data, options.ripdir); } GtkWidget * create_ripper_deststore_combo(void) { GtkWidget * combo = gtk_combo_box_new_text(); GtkTreeIter iter; int n = 0; int i; gtk_combo_box_append_text(GTK_COMBO_BOX(combo), _("(none)")); i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &iter, NULL, i++)) { char * name; store_t * data; gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter, MS_COL_DATA, &data, -1); if (data->type != STORE_TYPE_FILE) { continue; } if (((store_data_t *)data)->readonly) { continue; } gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter, MS_COL_NAME, &name, -1); gtk_combo_box_append_text(GTK_COMBO_BOX(combo), name); ++n; g_free(name); } if (n >= options.cdrip_deststore) { gtk_combo_box_set_active(GTK_COMBO_BOX(combo), options.cdrip_deststore); } else { gtk_combo_box_set_active(GTK_COMBO_BOX(combo), 0); } return combo; } /* ret: 0 - no store selected; 1 - store selected, iter set */ int get_ripper_deststore_iter(GtkTreeIter * iter_store) { GtkTreeIter iter; int selected = gtk_combo_box_get_active(GTK_COMBO_BOX(ripper_deststore_combo)); int i = 1, n = 0; options.cdrip_deststore = selected; if (selected == 0) { return 0; } while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &iter, NULL, n++)) { store_t * data; gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter, MS_COL_DATA, &data, -1); if (data->type != STORE_TYPE_FILE) { continue; } if (((store_data_t *)data)->readonly) { continue; } if (i == selected) { *iter_store = iter; return 1; } ++i; } return 0; } GtkWidget * create_ripper_format_combo(void) { GtkWidget * combo = gtk_combo_box_new_text(); int n = -1; #ifdef HAVE_SNDFILE gtk_combo_box_append_text(GTK_COMBO_BOX(combo), "WAV"); ++n; #endif /* HAVE_SNDFILE */ #ifdef HAVE_FLAC gtk_combo_box_append_text(GTK_COMBO_BOX(combo), "FLAC"); ++n; #endif /* HAVE_FLAC */ #ifdef HAVE_VORBISENC gtk_combo_box_append_text(GTK_COMBO_BOX(combo), "Ogg Vorbis"); ++n; #endif /* HAVE_VORBISENC */ #ifdef HAVE_LAME gtk_combo_box_append_text(GTK_COMBO_BOX(combo), "MP3"); ++n; #endif /* HAVE_LAME */ if (n >= options.cdrip_file_format) { gtk_combo_box_set_active(GTK_COMBO_BOX(combo), options.cdrip_file_format); } else { gtk_combo_box_set_active(GTK_COMBO_BOX(combo), 0); } return combo; } /* returns file_lib value */ int get_ripper_format(void) { int file_lib = -1; gchar * text = gtk_combo_box_get_active_text(GTK_COMBO_BOX(ripper_format_combo)); if (strcmp(text, "WAV") == 0) { file_lib = ENC_SNDFILE_LIB; } if (strcmp(text, "FLAC") == 0) { file_lib = ENC_FLAC_LIB; } if (strcmp(text, "Ogg Vorbis") == 0) { file_lib = ENC_VORBIS_LIB; } if (strcmp(text, "MP3") == 0) { file_lib = ENC_LAME_LIB; } g_free(text); return file_lib; } void ripper_bitrate_changed(GtkRange * range, gpointer data) { float val = gtk_range_get_value(range); gchar * text = gtk_combo_box_get_active_text(GTK_COMBO_BOX(ripper_format_combo)); if (strcmp(text, "FLAC") == 0) { int i = (int)val; char str[256]; switch (i) { case 0: case 8: snprintf(str, 255, "%d (%s)", i, (i == 0) ? _("fast") : _("best")); gtk_label_set_text(GTK_LABEL(ripper_bitrate_value_label), str); break; default: snprintf(str, 255, "%d", i); gtk_label_set_text(GTK_LABEL(ripper_bitrate_value_label), str); break; } } if (strcmp(text, "Ogg Vorbis") == 0) { int i = (int)val; char str[256]; snprintf(str, 255, "%d", i); gtk_label_set_text(GTK_LABEL(ripper_bitrate_value_label), str); } if (strcmp(text, "MP3") == 0) { int i = (int)val; char str[256]; #ifdef HAVE_LAME i = lame_encoder_validate_bitrate(i, 0); #endif /* HAVE_LAME */ snprintf(str, 255, "%d", i); gtk_label_set_text(GTK_LABEL(ripper_bitrate_value_label), str); } g_free(text); } void ripper_format_combo_changed(GtkWidget * widget, gpointer data) { gchar * text = gtk_combo_box_get_active_text(GTK_COMBO_BOX(widget)); if (strcmp(text, "WAV") == 0) { gtk_widget_hide(ripper_bitrate_scale); gtk_widget_hide(ripper_bitrate_label); gtk_widget_hide(ripper_bitrate_value_label); gtk_widget_hide(ripper_vbr_check); gtk_widget_hide(ripper_meta_check); } if (strcmp(text, "FLAC") == 0) { gtk_widget_show(ripper_bitrate_scale); gtk_widget_show(ripper_bitrate_label); gtk_label_set_text(GTK_LABEL(ripper_bitrate_label), _("Compression level:")); gtk_widget_show(ripper_bitrate_value_label); gtk_widget_hide(ripper_vbr_check); gtk_widget_show(ripper_meta_check); gtk_range_set_range(GTK_RANGE(ripper_bitrate_scale), 0, 8); gtk_range_set_value(GTK_RANGE(ripper_bitrate_scale), options.cdrip_bitrate); } if (strcmp(text, "Ogg Vorbis") == 0) { gtk_widget_show(ripper_bitrate_scale); gtk_widget_show(ripper_bitrate_label); gtk_label_set_text(GTK_LABEL(ripper_bitrate_label), _("Bitrate [kbps]:")); gtk_widget_show(ripper_bitrate_value_label); gtk_widget_hide(ripper_vbr_check); gtk_widget_show(ripper_meta_check); gtk_range_set_range(GTK_RANGE(ripper_bitrate_scale), 32, 320); gtk_range_set_value(GTK_RANGE(ripper_bitrate_scale), options.cdrip_bitrate); } if (strcmp(text, "MP3") == 0) { gtk_widget_show(ripper_bitrate_scale); gtk_widget_show(ripper_bitrate_label); gtk_label_set_text(GTK_LABEL(ripper_bitrate_label), _("Bitrate [kbps]:")); gtk_widget_show(ripper_bitrate_value_label); gtk_widget_show(ripper_vbr_check); gtk_widget_show(ripper_meta_check); gtk_range_set_range(GTK_RANGE(ripper_bitrate_scale), 32, 320); gtk_range_set_value(GTK_RANGE(ripper_bitrate_scale), options.cdrip_bitrate); } options.cdrip_file_format = get_ripper_format(); g_free(text); } void ripper_paranoia_toggled(GtkWidget * widget, gpointer * data) { gtk_widget_set_sensitive(ripper_maxretries_spinner, !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ripper_neverskip_check))); gtk_widget_set_sensitive(ripper_maxretries_label, !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ripper_neverskip_check))); } int ripper_handle_existing_record_iter(GtkTreeIter * iter) { int ret; if (gtk_tree_model_iter_n_children(GTK_TREE_MODEL(music_store), iter) == 0) { return 0; } ret = message_dialog(_("Artist/Album already existing, not empty"), ripper_dialog, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK_CANCEL, NULL, _("\nThe Music Store you selected has a matching Artist and " "Album, already containing some tracks. If you press OK, " "these tracks will be removed. The files themselves will " "be left intact, but they will be removed from the " "destination Music Store. Press Cancel to get back to " "change the Artist/Album or the destination Music Store.")); if (ret == GTK_RESPONSE_OK) { GtkTreeIter track_iter; gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &track_iter, iter, 0); while (store_file_remove_track(&track_iter)); music_store_mark_changed(iter); return 0; } return 1; } /* ret: 0 - ok, 1 - already found, user bailed out of overwriting */ int ripper_make_dest_iters(GtkTreeIter * store_iter, GtkTreeIter * artist_iter, GtkTreeIter * record_iter) { int i; int j; record_data_t * record_data; artist_data_t * artist_data; char str_year[16]; i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), artist_iter, store_iter, i++)) { char * artist_name; gtk_tree_model_get(GTK_TREE_MODEL(music_store), artist_iter, MS_COL_NAME, &artist_name, -1); if (g_utf8_collate(ripper_artist, artist_name)) { g_free(artist_name); continue; } j = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), record_iter, artist_iter, j++)) { char * record_name; gtk_tree_model_get(GTK_TREE_MODEL(music_store), record_iter, MS_COL_NAME, &record_name, -1); if (!g_utf8_collate(ripper_album, record_name)) { int ret = ripper_handle_existing_record_iter(record_iter); g_free(record_name); g_free(artist_name); return ret; } g_free(record_name); } /* create record */ if ((record_data = (record_data_t *)calloc(1, sizeof(record_data_t))) == NULL) { fprintf(stderr, "ripper_make_dest_iters: calloc error\n"); return 0; } record_data->year = ripper_year; snprintf(str_year, 15, "%d", ripper_year); gtk_tree_store_append(music_store, record_iter, artist_iter); gtk_tree_store_set(music_store, record_iter, MS_COL_NAME, ripper_album, MS_COL_SORT, str_year, MS_COL_DATA, record_data, -1); if (options.enable_ms_tree_icons) { gtk_tree_store_set(music_store, record_iter, MS_COL_ICON, icon_record, -1); } music_store_mark_changed(record_iter); g_free(artist_name); return 0; } /* create both artist and record */ if ((artist_data = (artist_data_t *)calloc(1, sizeof(artist_data_t))) == NULL) { fprintf(stderr, "ripper_make_dest_iters: calloc error\n"); return 0; } if ((record_data = (record_data_t *)calloc(1, sizeof(record_data_t))) == NULL) { fprintf(stderr, "ripper_make_dest_iters: calloc error\n"); return 0; } gtk_tree_store_append(music_store, artist_iter, store_iter); gtk_tree_store_set(music_store, artist_iter, MS_COL_NAME, ripper_artist, MS_COL_SORT, ripper_artist, MS_COL_DATA, artist_data, -1); if (options.enable_ms_tree_icons) { gtk_tree_store_set(music_store, artist_iter, MS_COL_ICON, icon_artist, -1); } record_data->year = ripper_year; snprintf(str_year, 15, "%d", ripper_year); gtk_tree_store_append(music_store, record_iter, artist_iter); gtk_tree_store_set(music_store, record_iter, MS_COL_NAME, ripper_album, MS_COL_SORT, str_year, MS_COL_DATA, record_data, -1); if (options.enable_ms_tree_icons) { gtk_tree_store_set(music_store, record_iter, MS_COL_ICON, icon_record, -1); } music_store_mark_changed(record_iter); return 0; } int cd_ripper_dialog(cdda_drive_t * drive, GtkTreeIter * iter) { GtkWidget * notebook; GtkWidget * table; GtkWidget * hbox; GtkWidget * button; GtkWidget * frame; GtkWidget * vbox_source; GtkWidget * vbox_dest; GtkWidget * vbox_dest1; GtkWidget * vbox_format; GtkWidget * vbox_para; GtkWidget * vbox_para1; GtkWidget * source_tree; GtkWidget * viewport; GtkWidget * scrolled_win; GtkCellRenderer * cell; GtkTreeViewColumn * column; ripper_dialog = gtk_dialog_new_with_buttons(_("Rip CD"), GTK_WINDOW(browser_window), GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL); gtk_window_set_position(GTK_WINDOW(ripper_dialog), GTK_WIN_POS_CENTER); gtk_window_set_default_size(GTK_WINDOW(ripper_dialog), 400, -1); gtk_dialog_set_default_response(GTK_DIALOG(ripper_dialog), GTK_RESPONSE_REJECT); notebook = gtk_notebook_new(); gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_TOP); gtk_container_add(GTK_CONTAINER(GTK_DIALOG(ripper_dialog)->vbox), notebook); /* Source selection */ vbox_source = create_notebook_page(notebook, _("Source")); table = gtk_table_new(6, 2, FALSE); gtk_box_pack_start(GTK_BOX(vbox_source), table, FALSE, FALSE, 0); insert_label_entry(table, _("Artist:"), &ripper_artist_entry, drive->disc.artist_name, 0, 1, TRUE); insert_label_entry(table, _("Album:"), &ripper_album_entry, drive->disc.record_name, 1, 2, TRUE); insert_label_spin(table, _("Year:"), &ripper_year_spinner, drive->disc.year, 2, 3); insert_label_entry(table, _("Genre:"), &ripper_genre_entry, drive->disc.genre, 3, 4, TRUE); if (ripper_source_store == NULL) { ripper_source_store = gtk_list_store_new(3, G_TYPE_BOOLEAN, /* rip this track? */ G_TYPE_INT, /* track number */ G_TYPE_STRING); /* track name */ } else { gtk_list_store_clear(ripper_source_store); } ripper_source_store_make(iter); viewport = gtk_viewport_new(NULL, NULL); gtk_table_attach(GTK_TABLE(table), viewport, 0, 2, 4, 5, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 5); scrolled_win = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_win), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_container_add(GTK_CONTAINER(viewport), scrolled_win); source_tree = gtk_tree_view_new(); gtk_tree_view_set_model(GTK_TREE_VIEW(source_tree), GTK_TREE_MODEL(ripper_source_store)); gtk_widget_set_size_request(source_tree, -1, 300); gtk_container_add(GTK_CONTAINER(scrolled_win), source_tree); gtk_tree_view_set_enable_search(GTK_TREE_VIEW(source_tree), FALSE); if (options.enable_ms_rules_hint) { gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(source_tree), TRUE); } cell = gtk_cell_renderer_toggle_new(); g_object_set(cell, "activatable", TRUE, NULL); g_signal_connect(cell, "toggled", (GCallback)ripper_cell_toggled_cb, NULL); column = gtk_tree_view_column_new_with_attributes(_("Rip"), cell, "active", 0, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(source_tree), GTK_TREE_VIEW_COLUMN(column)); cell = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes(_("No."), cell, "text", 1, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(source_tree), GTK_TREE_VIEW_COLUMN(column)); cell = gtk_cell_renderer_text_new(); g_object_set(cell, "editable", TRUE, NULL); g_signal_connect(cell, "edited", (GCallback)ripper_cell_edited_cb, NULL); column = gtk_tree_view_column_new_with_attributes(_("Title"), cell, "text", 2, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(source_tree), GTK_TREE_VIEW_COLUMN(column)); hbox = gtk_hbox_new(FALSE, 0); gtk_container_set_border_width(GTK_CONTAINER(hbox), 2); gtk_table_attach(GTK_TABLE(table), hbox, 0, 2, 5, 6, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); gtk_box_pack_start(GTK_BOX(hbox), gtk_label_new(_("Select")), FALSE, FALSE, 5); button = gtk_button_new_with_label(_("All")); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(ripper_set_all_cb), (gpointer)TRUE); gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 5); button = gtk_button_new_with_label(_("None")); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(ripper_set_all_cb), (gpointer)FALSE); gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 5); /* Output */ vbox_dest = create_notebook_page(notebook, _("Output")); vbox_dest1 = create_frame_on_page(vbox_dest, _("Destination")); frame = gtk_frame_new(_("Target directory for ripped files")); gtk_box_pack_start(GTK_BOX(vbox_dest1), frame, FALSE, FALSE, 2); gtk_container_set_border_width(GTK_CONTAINER(frame), 5); hbox = gtk_hbox_new(FALSE, 0); gtk_container_set_border_width(GTK_CONTAINER(hbox), 5); gtk_container_add(GTK_CONTAINER(frame), hbox); ripper_destdir_entry = gtk_entry_new(); gtk_entry_set_max_length(GTK_ENTRY(ripper_destdir_entry), MAXLEN-1); gtk_entry_set_text(GTK_ENTRY(ripper_destdir_entry), options.ripdir); gtk_box_pack_start(GTK_BOX(hbox), ripper_destdir_entry, TRUE, TRUE, 5); button = gui_stock_label_button(_("_Browse..."), GTK_STOCK_OPEN); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(ripper_destdir_browse_cb), (gpointer)ripper_destdir_entry); gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 4); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox_dest1), hbox, FALSE, FALSE, 5); gtk_box_pack_start(GTK_BOX(hbox), gtk_label_new(_("Add to Music Store")), FALSE, FALSE, 7); ripper_deststore_combo = create_ripper_deststore_combo(); gtk_box_pack_start(GTK_BOX(hbox), ripper_deststore_combo, TRUE, TRUE, 5); vbox_format = create_frame_on_page(vbox_dest, _("Format")); table = gtk_table_new(4, 2, TRUE); gtk_box_pack_start(GTK_BOX(vbox_format), table, TRUE, TRUE, 0); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), gtk_label_new(_("File format:")), FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(table), hbox, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 5, 4); ripper_format_combo = create_ripper_format_combo(); gtk_table_attach(GTK_TABLE(table), ripper_format_combo, 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 5, 2); hbox = gtk_hbox_new(FALSE, 0); ripper_bitrate_label = gtk_label_new(_("Compression level:")); gtk_box_pack_start(GTK_BOX(hbox), ripper_bitrate_label, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(table), hbox, 0, 1, 1, 2, GTK_FILL, GTK_FILL, 5, 0); ripper_bitrate_scale = gtk_hscale_new_with_range(0, 8, 1); g_signal_connect(G_OBJECT(ripper_bitrate_scale), "value-changed", G_CALLBACK(ripper_bitrate_changed), NULL); gtk_scale_set_draw_value(GTK_SCALE(ripper_bitrate_scale), FALSE); gtk_scale_set_digits(GTK_SCALE(ripper_bitrate_scale), 0); gtk_widget_set_size_request(ripper_bitrate_scale, 180, -1); gtk_table_attach(GTK_TABLE(table), ripper_bitrate_scale, 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, GTK_FILL, 5, 0); ripper_bitrate_value_label = gtk_label_new("0 (fast)"); gtk_table_attach(GTK_TABLE(table), ripper_bitrate_value_label, 1, 2, 2, 3, GTK_EXPAND | GTK_FILL, GTK_FILL, 5, 0); ripper_vbr_check = gtk_check_button_new_with_label(_("VBR encoding")); gtk_widget_set_name(ripper_vbr_check, "check_on_notebook"); gtk_table_attach(GTK_TABLE(table), ripper_vbr_check, 0, 1, 2, 3, GTK_FILL, GTK_FILL, 5, 0); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ripper_vbr_check), options.cdrip_vbr); ripper_meta_check = gtk_check_button_new_with_label(_("Tag files with metadata")); gtk_widget_set_name(ripper_meta_check, "check_on_notebook"); gtk_table_attach(GTK_TABLE(table), ripper_meta_check, 0, 2, 3, 4, GTK_EXPAND | GTK_FILL, GTK_FILL, 5, 4); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ripper_meta_check), options.cdrip_metadata); g_signal_connect(G_OBJECT(ripper_format_combo), "changed", G_CALLBACK(ripper_format_combo_changed), NULL); /* Paranoia */ vbox_para = create_notebook_page(notebook, _("Paranoia")); vbox_para1 = create_frame_on_page(vbox_para, _("Paranoia error correction")); gtk_container_set_border_width(GTK_CONTAINER(vbox_para1), 5); ripper_overlap_check = gtk_check_button_new_with_label(_("Perform overlapped reads")); gtk_widget_set_name(ripper_overlap_check, "check_on_notebook"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ripper_overlap_check), TRUE); gtk_box_pack_start(GTK_BOX(vbox_para1), ripper_overlap_check, FALSE, FALSE, 3); ripper_verify_check = gtk_check_button_new_with_label(_("Verify data integrity")); gtk_widget_set_name(ripper_verify_check, "check_on_notebook"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ripper_verify_check), TRUE); gtk_box_pack_start(GTK_BOX(vbox_para1), ripper_verify_check, FALSE, FALSE, 3); ripper_neverskip_check = gtk_check_button_new_with_label(_("Unlimited retry on failed reads (never skip)")); gtk_widget_set_name(ripper_neverskip_check, "check_on_notebook"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ripper_neverskip_check), TRUE); gtk_box_pack_start(GTK_BOX(vbox_para1), ripper_neverskip_check, FALSE, FALSE, 3); g_signal_connect(ripper_neverskip_check, "toggled", G_CALLBACK(ripper_paranoia_toggled), NULL); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox_para1), hbox, FALSE, FALSE, 3); ripper_maxretries_label = gtk_label_new(_("Maximum number of retries:")); gtk_widget_set_sensitive(ripper_maxretries_label, FALSE); gtk_box_pack_start(GTK_BOX(hbox), ripper_maxretries_label, FALSE, FALSE, 35); ripper_maxretries_spinner = gtk_spin_button_new_with_range(1, 50, 1); gtk_spin_button_set_value(GTK_SPIN_BUTTON(ripper_maxretries_spinner), options.cdda_paranoia_maxretries); gtk_widget_set_sensitive(ripper_maxretries_spinner, FALSE); gtk_box_pack_start(GTK_BOX(hbox), ripper_maxretries_spinner, FALSE, FALSE, 5); gtk_widget_show_all(ripper_dialog); ripper_format_combo_changed(ripper_format_combo, NULL); ripper_display: destdir[0] = '\0'; if (aqualung_dialog_run(GTK_DIALOG(ripper_dialog)) == GTK_RESPONSE_ACCEPT) { char * pdestdir = g_filename_from_utf8(gtk_entry_get_text(GTK_ENTRY(ripper_destdir_entry)), -1, NULL, NULL, NULL); if ((pdestdir == NULL) || (pdestdir[0] == '\0')) { gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook), 1); gtk_widget_grab_focus(ripper_destdir_entry); g_free(pdestdir); goto ripper_display; } normalize_filename(pdestdir, destdir); g_free(pdestdir); if (access(destdir, R_OK | W_OK) != 0) { message_dialog(_("Error"), ripper_dialog, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, NULL, _("\nDestination directory is not read-write accessible!")); gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook), 1); gtk_widget_grab_focus(ripper_destdir_entry); goto ripper_display; } strncpy(options.ripdir, destdir, MAXLEN-1); options.cdrip_file_format = ripper_format = get_ripper_format(); options.cdrip_bitrate = ripper_bitrate = gtk_range_get_value(GTK_RANGE(ripper_bitrate_scale)); set_option_from_toggle(ripper_vbr_check, &ripper_vbr); options.cdrip_vbr = ripper_vbr; set_option_from_toggle(ripper_meta_check, &ripper_meta); options.cdrip_metadata = ripper_meta; set_option_from_entry(ripper_artist_entry, ripper_artist, MAXLEN); set_option_from_entry(ripper_album_entry, ripper_album, MAXLEN); set_option_from_entry(ripper_genre_entry, ripper_genre, MAXLEN); set_option_from_spin(ripper_year_spinner, &ripper_year); ripper_write_to_store = get_ripper_deststore_iter(&ripper_dest_store); if (ripper_write_to_store) { if (ripper_make_dest_iters(&ripper_dest_store, &ripper_dest_artist, &ripper_dest_record) == 1) { goto ripper_display; } } ripper_paranoia_mode = (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ripper_overlap_check)) ? PARANOIA_MODE_OVERLAP : 0) | (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ripper_verify_check)) ? PARANOIA_MODE_VERIFY : 0) | (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ripper_neverskip_check)) ? PARANOIA_MODE_NEVERSKIP : 0); set_option_from_spin(ripper_maxretries_spinner, &ripper_paranoia_maxretries); ripper_source_write_back(iter, ripper_artist, ripper_album, ripper_genre, ripper_year); gtk_widget_destroy(ripper_dialog); return 1; } else { gtk_widget_destroy(ripper_dialog); return 0; } } void sector_to_str(int sector, char * str) { int m, s, f; m = sector / (60*75); s = sector / 75 - m * 60; f = sector % 75; snprintf(str, MAXLEN-1, "%d [%02d:%02d.%02d]", sector, m, s, f); } void ripper_prog_store_make(cdda_drive_t * drive) { GtkTreeIter source_iter; GtkTreeIter iter; int n = 0; char begin[MAXLEN]; char length[MAXLEN]; total_sectors = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(ripper_source_store), &source_iter, NULL, n++)) { gboolean b; int len; char num[16]; gtk_tree_model_get(GTK_TREE_MODEL(ripper_source_store), &source_iter, 0, &b, -1); if (!b) continue; len = drive->disc.toc[n] - drive->disc.toc[n-1]; total_sectors += len; sector_to_str(drive->disc.toc[n-1], begin); sector_to_str(len, length); sprintf(num, "%d.", n); gtk_list_store_append(ripper_prog_store, &iter); gtk_list_store_set(ripper_prog_store, &iter, 0, num, 1, begin, 2, length, 3, 0, -1); } sector_to_str(total_sectors, length); gtk_list_store_append(ripper_prog_store, &iter); gtk_list_store_set(ripper_prog_store, &iter, 0, _("Total"), 1, _("(audio only)"), 2, length, 3, 0, -1); } void ripper_prog_window_close(GtkWidget * widget, gpointer data) { ripper_thread_busy = 0; unregister_toplevel_window(ripper_prog_window); gtk_widget_destroy(ripper_prog_window); ripper_prog_window = NULL; gtk_list_store_clear(ripper_source_store); gtk_list_store_clear(ripper_prog_store); } void ripper_cancel(GtkWidget * widget, gpointer data) { ripper_prog_window_close(NULL, NULL); } gboolean ripper_prog_window_state_changed(GtkWidget * widget, GdkEventWindowState * event, gpointer user_data) { if ((ripper_prog_window_visible = !(event->new_window_state & GDK_WINDOW_STATE_ICONIFIED))) { gtk_window_set_title(GTK_WINDOW(ripper_prog_window), _("Ripping CD tracks")); } return FALSE; } void ripper_window(void) { GtkWidget * vbox; GtkWidget * viewport; GtkWidget * scrolled_win; GtkWidget * prog_tree; GtkCellRenderer * cell; GtkTreeViewColumn * column; ripper_prog_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); register_toplevel_window(ripper_prog_window, TOP_WIN_SKIN | TOP_WIN_TRAY); gtk_window_set_title(GTK_WINDOW(ripper_prog_window), _("Ripping CD tracks")); gtk_window_set_position(GTK_WINDOW(ripper_prog_window), GTK_WIN_POS_CENTER); g_signal_connect(G_OBJECT(ripper_prog_window), "delete_event", G_CALLBACK(ripper_prog_window_close), NULL); g_signal_connect(G_OBJECT(ripper_prog_window), "window_state_event", G_CALLBACK(ripper_prog_window_state_changed), NULL); gtk_container_set_border_width(GTK_CONTAINER(ripper_prog_window), 5); vbox = gtk_vbox_new(FALSE, 0); gtk_container_add(GTK_CONTAINER(ripper_prog_window), vbox); viewport = gtk_viewport_new(NULL, NULL); gtk_box_pack_start(GTK_BOX(vbox), viewport, TRUE, TRUE, 0); scrolled_win = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_win), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_container_add(GTK_CONTAINER(viewport), scrolled_win); prog_tree = gtk_tree_view_new(); gtk_tree_view_set_model(GTK_TREE_VIEW(prog_tree), GTK_TREE_MODEL(ripper_prog_store)); gtk_widget_set_size_request(prog_tree, 500, 320); gtk_container_add(GTK_CONTAINER(scrolled_win), prog_tree); gtk_tree_view_set_enable_search(GTK_TREE_VIEW(prog_tree), FALSE); gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(prog_tree)), GTK_SELECTION_NONE); if (options.enable_ms_rules_hint) { gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(prog_tree), TRUE); } cell = gtk_cell_renderer_text_new(); g_object_set((gpointer)cell, "xalign", 1.0, NULL); column = gtk_tree_view_column_new_with_attributes(_("No."), cell, "text", 0, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(prog_tree), GTK_TREE_VIEW_COLUMN(column)); cell = gtk_cell_renderer_text_new(); g_object_set((gpointer)cell, "xalign", 1.0, NULL); column = gtk_tree_view_column_new_with_attributes(_("Begin"), cell, "text", 1, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(prog_tree), GTK_TREE_VIEW_COLUMN(column)); cell = gtk_cell_renderer_text_new(); g_object_set((gpointer)cell, "xalign", 1.0, NULL); column = gtk_tree_view_column_new_with_attributes(_("Length"), cell, "text", 2, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(prog_tree), GTK_TREE_VIEW_COLUMN(column)); cell = gtk_cell_renderer_progress_new(); column = gtk_tree_view_column_new_with_attributes(_("Progress"), cell, "value", 3, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(prog_tree), GTK_TREE_VIEW_COLUMN(column)); ripper_hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_end(GTK_BOX(vbox), ripper_hbox, FALSE, TRUE, 5); ripper_close_when_ready_check = gtk_check_button_new_with_label(_("Close window when complete")); gtk_widget_set_name(ripper_close_when_ready_check, "check_on_window"); gtk_box_pack_start(GTK_BOX(ripper_hbox), ripper_close_when_ready_check, FALSE, TRUE, 0); ripper_cancel_button = gui_stock_label_button (_("Abort"), GTK_STOCK_CANCEL); g_signal_connect(ripper_cancel_button, "clicked", G_CALLBACK(ripper_cancel), NULL); gtk_box_pack_end(GTK_BOX(ripper_hbox), ripper_cancel_button, FALSE, TRUE, 0); gtk_widget_grab_focus(ripper_cancel_button); gtk_widget_show_all(ripper_prog_window); } gboolean ripper_update_status(gpointer pdata) { GtkTreeIter iter; int data = GPOINTER_TO_INT(pdata); int track_no = (data & 0xff0000) >> 16; int prog_track = (data & 0xff00) >> 8; int prog_total = data & 0xff; int n_children = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(ripper_prog_store), NULL); if (!ripper_prog_window) return FALSE; if (prog_track > 100) prog_track = 100; if (prog_total > 100) prog_total = 100; if (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(ripper_prog_store), &iter, NULL, track_no)) { gtk_list_store_set(ripper_prog_store, &iter, 3, prog_track, -1); } if (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(ripper_prog_store), &iter, NULL, n_children-1)) { gtk_list_store_set(ripper_prog_store, &iter, 3, prog_total, -1); } if (!ripper_prog_window_visible) { char title[MAXLEN]; snprintf(title, MAXLEN, "%d%% - %s", prog_total, _("Ripping CD tracks")); gtk_window_set_title(GTK_WINDOW(ripper_prog_window), title); } if (prog_total == 100) { if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ripper_close_when_ready_check))) { ripper_prog_window_close(NULL, NULL); } else { gtk_widget_destroy(ripper_cancel_button); gtk_widget_destroy(ripper_close_when_ready_check); ripper_cancel_button = gui_stock_label_button (_("Close"), GTK_STOCK_CLOSE); g_signal_connect(ripper_cancel_button, "clicked", G_CALLBACK(ripper_cancel), NULL); gtk_box_pack_end(GTK_BOX(ripper_hbox), ripper_cancel_button, FALSE, TRUE, 0); gtk_widget_grab_focus(ripper_cancel_button); } } return FALSE; } void ripper_meta_add(metadata_t * meta, int tags, int type, char * str, int val) { int tag = META_TAG_MAX; while (tag) { if (tags & tag) { meta_frame_t * frame = meta_frame_new(); frame->tag = tag; frame->type = type; frame->field_val = strdup(str); frame->int_val = val; metadata_add_frame(meta, frame); } tag >>= 1; } } void * ripper_thread(void * arg) { cdda_drive_t * drive = (cdda_drive_t *)arg; long hash; int n = 0; int track_cnt = 0; int total_sectors_read = 0; GtkTreeIter source_iter; AQUALUNG_THREAD_DETACH() hash = calc_cdda_hash(&drive->disc); while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(ripper_source_store), &source_iter, NULL, n++)) { gboolean b; int no; char * name; char * ext = "raw"; int tags = 0; char decoder_filename[256]; int track_sectors = 0; int track_sectors_read = 0; file_decoder_t * fdec; file_encoder_t * fenc; encoder_mode_t mode; float buf[2*BUFSIZE]; int n_read; int prog_track; int prog_total; memset(&mode, 0, sizeof(encoder_mode_t)); gtk_tree_model_get(GTK_TREE_MODEL(ripper_source_store), &source_iter, 0, &b, -1); if (!b) continue; gtk_tree_model_get(GTK_TREE_MODEL(ripper_source_store), &source_iter, 1, &no, 2, &name, -1); if (ripper_thread_busy == 0) { return NULL; } track_sectors = drive->disc.toc[no] - drive->disc.toc[no-1]; switch (ripper_format) { case ENC_SNDFILE_LIB: ext = "wav"; tags = 0; break; case ENC_FLAC_LIB: ext = "flac"; tags = META_TAG_OXC; break; case ENC_VORBIS_LIB: ext = "ogg"; tags = META_TAG_OXC; break; case ENC_LAME_LIB: ext = "mp3"; tags = META_TAG_ID3v1 | META_TAG_ID3v2 | META_TAG_APE; break; } snprintf(decoder_filename, 255, "CDDA %s %lX %d", drive->device_path, hash, no); snprintf(mode.filename, MAXLEN-1, "%s/track%02d.%s", destdir, no, ext); mode.file_lib = ripper_format; mode.sample_rate = 44100; mode.channels = 2; if (mode.file_lib == ENC_FLAC_LIB) { mode.clevel = ripper_bitrate; } else if (mode.file_lib == ENC_VORBIS_LIB) { mode.bps = ripper_bitrate * 1000; } else if (mode.file_lib == ENC_LAME_LIB) { mode.bps = ripper_bitrate * 1000; mode.vbr = ripper_vbr; } mode.write_meta = ripper_meta; if (mode.write_meta) { mode.meta = metadata_new(); char date[8]; snprintf(date, 7, "%d", ripper_year); ripper_meta_add(mode.meta, tags, META_FIELD_ARTIST, ripper_artist, 0); ripper_meta_add(mode.meta, tags, META_FIELD_ALBUM, ripper_album, 0); ripper_meta_add(mode.meta, tags, META_FIELD_TITLE, name, 0); ripper_meta_add(mode.meta, tags, META_FIELD_GENRE, ripper_genre, 0); ripper_meta_add(mode.meta, tags, META_FIELD_DATE, date, 0); ripper_meta_add(mode.meta, tags, META_FIELD_TRACKNO, "", no); } fdec = file_decoder_new(); fenc = file_encoder_new(); if (file_decoder_open(fdec, decoder_filename)) { return NULL; } if (file_encoder_open(fenc, &mode)) { return NULL; } cdda_decoder_set_mode(((decoder_t *)fdec->pdec), 100, /* max drive speed */ ripper_paranoia_mode, ripper_paranoia_maxretries); while (ripper_thread_busy) { n_read = file_decoder_read(fdec, buf, BUFSIZE); file_encoder_write(fenc, buf, n_read); ++track_sectors_read; ++total_sectors_read; prog_track = 100 * track_sectors_read / track_sectors; prog_total = 100 * total_sectors_read / total_sectors; if ((track_sectors_read % 64 == 0) || (track_sectors_read == track_sectors)) aqualung_idle_add(ripper_update_status, GINT_TO_POINTER(((track_cnt & 0xff) << 16) | ((prog_track & 0xff) << 8) | (prog_total & 0xff))); if ((track_sectors_read >= track_sectors) || (n_read < BUFSIZE)) break; } if (ripper_write_to_store && ripper_thread_busy && gtk_tree_store_iter_is_valid(music_store, &ripper_dest_record)) { GtkTreeIter iter; char sort_name[3]; track_data_t * track_data; if ((track_data = (track_data_t *)calloc(1, sizeof(track_data_t))) == NULL) { fprintf(stderr, "ripper_thread: calloc error\n"); return 0; } track_data->file = strdup(mode.filename); track_data->duration = track_sectors_read / 75.0; track_data->volume = 1.0f; snprintf(sort_name, 3, "%02d", no); gtk_tree_store_append(music_store, &iter, &ripper_dest_record); gtk_tree_store_set(music_store, &iter, MS_COL_NAME, name, MS_COL_SORT, sort_name, MS_COL_DATA, track_data, -1); if (options.enable_ms_tree_icons) { gtk_tree_store_set(music_store, &iter, MS_COL_ICON, icon_track, -1); } music_store_mark_changed(&iter); } file_decoder_close(fdec); file_encoder_close(fenc); file_decoder_delete(fdec); file_encoder_delete(fenc); if (mode.meta != NULL) { metadata_free(mode.meta); } ++track_cnt; } return NULL; } void cd_ripper(cdda_drive_t * drive, GtkTreeIter * iter) { if (cd_ripper_dialog(drive, iter)) { if (ripper_prog_store == NULL) { ripper_prog_store = gtk_list_store_new(4, G_TYPE_STRING, /* track number */ G_TYPE_STRING, /* begin sector */ G_TYPE_STRING, /* length (sectors) */ G_TYPE_INT); /* progress (%) */ } else { gtk_list_store_clear(ripper_prog_store); } ripper_prog_store_make(drive); ripper_window(); ripper_thread_busy = 1; AQUALUNG_THREAD_CREATE(ripper_thread_id, NULL, ripper_thread, drive); } } #else GtkWidget * ripper_prog_window = NULL; #endif /* HAVE_CD_RIPPER */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/core.h0000644000175000001440000000723011243322761013005 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: core.h 1073 2009-08-20 19:35:23Z tszilagyi $ */ #ifndef _CORE_H #define _CORE_H #include #ifdef _WIN32 #include #else #include #endif #include "common.h" #ifdef HAVE_ALSA #define AlSA_PCM_NEW_HW_PARAMS_API #include #endif /* HAVE_ALSA */ #ifdef HAVE_JACK #include #endif /* HAVE_JACK */ /* output drivers */ #ifdef HAVE_OSS #define OSS_DRIVER 1 #endif /* HAVE_OSS */ #ifdef HAVE_ALSA #define ALSA_DRIVER 2 #endif /* HAVE_ALSA */ #ifdef HAVE_JACK #define JACK_DRIVER 3 #endif /* HAVE_JACK */ #ifdef _WIN32 #define WIN32_DRIVER 4 #endif /* _WIN32 */ #ifdef HAVE_SNDIO #define SNDIO_DRIVER 5 #include #endif /* HAVE_SNDIO */ #ifdef HAVE_PULSE #define PULSE_DRIVER 6 #include #endif /* HAVE_PULSE */ #define MAX_SAMPLERATE 96000 /* audio ringbuffer size in stereo frames */ #define RB_AUDIO_SIZE 32768 /* control ringbuffer size in bytes */ #define RB_CONTROL_SIZE 32768 /* SRC settings */ #ifdef HAVE_SRC #define MAX_RATIO 24 #else #define MAX_RATIO 2 #endif /* HAVE_SRC */ typedef struct _thread_info { AQUALUNG_THREAD_DECLARE(disk_thread_id) #ifdef HAVE_SNDIO AQUALUNG_THREAD_DECLARE(sndio_thread_id) struct sio_hdl * sndio_hdl; short * sndio_short_buf; #endif /* HAVE_SNDIO */ #ifdef HAVE_OSS AQUALUNG_THREAD_DECLARE(oss_thread_id) int fd_oss; short * oss_short_buf; #endif /* HAVE_OSS */ #ifdef HAVE_ALSA AQUALUNG_THREAD_DECLARE(alsa_thread_id) char * pcm_name; snd_pcm_t * pcm_handle; snd_pcm_hw_params_t * hwparams; snd_pcm_uframes_t n_frames; int is_output_32bit; short * alsa_short_buf; int * alsa_int_buf; #endif /* HAVE_ALSA */ #ifdef _WIN32 AQUALUNG_THREAD_DECLARE(win32_thread_id) #endif /* _WIN32 */ #ifdef HAVE_PULSE AQUALUNG_THREAD_DECLARE(pulse_thread_id) pa_simple *pa; pa_sample_spec pa_spec; short * pa_short_buf; #endif /* HAVE_PULSE */ u_int32_t rb_size; unsigned long in_SR; unsigned long in_SR_prev; unsigned long out_SR; volatile int is_streaming; volatile int is_mono; } thread_info_t; /* command numbers from gui to disk */ #define CMD_CUE 1 #define CMD_PAUSE 2 #define CMD_RESUME 3 #define CMD_FINISH 4 #define CMD_SEEKTO 5 #define CMD_STOPWOFL 6 /* command numbers from disk to gui */ #define CMD_FILEREQ 7 #define CMD_FILEINFO 8 #define CMD_STATUS 9 #define CMD_METABLOCK 10 /* command numbers from disk to output */ #define CMD_FLUSH 11 typedef struct _cue_t { char * filename; float voladj; } cue_t; typedef struct _status_t { long long sample_pos; long long samples_left; long long sample_offset; unsigned long sample_rate; } status_t; typedef struct _seek_t { long long seek_to_pos; } seek_t; void jack_client_start(void); #define db2lin(x) ((x) > -90.0f ? powf(10.0f, (x) * 0.05f) : 0.0f) #endif /* _CORE_H */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/core.c0000644000175000001440000024772211324145461013014 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: core.c 1101 2010-01-15 20:07:01Z tszilagyi $ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef _WIN32 #include #else #include #endif /* _WIN32 */ #ifdef HAVE_SRC #include #endif /* HAVE_SRC */ #ifdef HAVE_SNDIO #include #endif /* HAVE_SNDIO */ #ifdef HAVE_OSS #include #include #ifdef __FreeBSD__ #include #else #ifdef __OpenBSD__ #include #else #include #endif /* __OpenBSD__ */ #endif /* __FreeBSD__ */ #endif /* HAVE_OSS */ #ifdef HAVE_JACK #include #include #endif /* HAVE_JACK */ #ifdef _WIN32 #include #include #endif /* _WIN32 */ #ifdef HAVE_PULSE #include #include #endif /* HAVE_PULSE */ #include "common.h" #include "utils.h" #include "version.h" #include "rb.h" #include "options.h" #include "decoder/file_decoder.h" #include "transceiver.h" #include "gui_main.h" #include "plugin.h" #include "i18n.h" #include "cdda.h" #ifdef HAVE_CDDA #include "decoder/dec_cdda.h" #endif /* HAVE_CDDA */ #include "core.h" extern options_t options; /* JACK data */ #ifdef HAVE_JACK jack_client_t * jack_client; jack_port_t * out_L_port; jack_port_t * out_R_port; char * client_name = NULL; u_int32_t jack_nframes; int jack_is_shutdown; int auto_connect = 0; int default_ports = 1; char * user_port1 = NULL; char * user_port2 = NULL; #endif /* HAVE_JACK */ const size_t sample_size = sizeof(float); gint playlist_state, browser_state; #ifndef OSS_DEVICE #ifdef __OpenBSD__ #define OSS_DEVICE "/dev/audio" #else #define OSS_DEVICE "/dev/dsp" #endif /* __OpenBSD__ */ #endif /* OSS_DEVICE */ /* The name of the output device e.g. "/dev/dsp" or "plughw:0,0" */ char * device_name = NULL; /***** disk thread stuff *****/ unsigned long long sample_offset; status_t disk_thread_status; int output = 0; /* oss/alsa/jack */ int src_type_parsed = 0; /* Synchronization between disk thread and output thread */ AQUALUNG_MUTEX_DECLARE_INIT(disk_thread_lock) AQUALUNG_COND_DECLARE_INIT(disk_thread_wake) rb_t * rb; /* this is the audio stream carrier ringbuffer */ rb_t * rb_disk2out; rb_t * rb_out2disk; /* Communication between gui thread and disk thread */ rb_t * rb_gui2disk; rb_t * rb_disk2gui; double left_gain = 1.0; double right_gain = 1.0; /* LADSPA stuff */ float * l_buf = NULL; float * r_buf = NULL; #ifdef HAVE_LADSPA volatile int plugin_lock = 0; unsigned long ladspa_buflen = 0; int n_plugins = 0; plugin_instance * plugin_vect[MAX_PLUGINS]; #endif /* HAVE_LADSPA */ /* remote control */ extern char * tab_name; extern int immediate_start; /* return 1 if conversion is possible, 0 if not */ int sample_rates_ok(int out_SR, int file_SR) { #ifdef HAVE_SRC float src_ratio; src_ratio = 1.0 * out_SR / file_SR; if (!src_is_valid_ratio(src_ratio) || src_ratio > MAX_RATIO || src_ratio < 1.0/MAX_RATIO) { fprintf(stderr, "core.c/sample_rates_ok(): too big difference between input and " "output sample rate!\n"); #else if (out_SR != file_SR) { fprintf(stderr, "Input file's samplerate (%d Hz) and output samplerate (%d Hz) differ, " "and\nAqualung is compiled without Sample Rate Converter support. To play " "this file,\nyou have to build Aqualung with internal Sample Rate Converter " "support,\nor set the playback sample rate to match the file's sample rate." "\n", file_SR, out_SR); #endif /* HAVE_SRC */ return 0; } return 1; } #ifdef HAVE_CDDA int same_disc_next_track(char * filename, char * filename_prev) { char device[CDDA_MAXLEN]; char device_prev[CDDA_MAXLEN]; int track, track_prev; long hash, hash_prev; if ((strlen(filename) < 4) || (filename[0] != 'C') || (filename[1] != 'D') || (filename[2] != 'D') || (filename[3] != 'A')) return 0; if ((strlen(filename_prev) < 4) || (filename_prev[0] != 'C') || (filename_prev[1] != 'D') || (filename_prev[2] != 'D') || (filename_prev[3] != 'A')) return 0; if (sscanf(filename, "CDDA %s %lX %u", device, &hash, &track) < 3) return 0; if (sscanf(filename_prev, "CDDA %s %lX %u", device_prev, &hash_prev, &track_prev) < 3) return 0; if (strcmp(device, device_prev) != 0) return 0; if (hash != hash_prev) return 0; return (track == track_prev + 1) ? 1 : 0; } #endif /* HAVE_CDDA */ /* roll back sample_offset samples, if possible */ void rollback(rb_t * rb, file_decoder_t * fdec, double src_ratio, u_int32_t playback_offset) { if (playback_offset < fdec->fileinfo.total_samples - fdec->samples_left) file_decoder_seek(fdec, fdec->fileinfo.total_samples - fdec->samples_left - playback_offset); else file_decoder_seek(fdec, 0); } /* returns number of samples in rb and output driver buffer */ u_int32_t flush_output(double src_ratio) { u_int32_t driver_offset; char send_cmd = CMD_FLUSH; struct timespec req_time; struct timespec rem_time; req_time.tv_sec = 0; req_time.tv_nsec = 1000000; sample_offset = rb_read_space(rb) / (2 * sample_size) * src_ratio; rb_write(rb_disk2out, &send_cmd, 1); while (rb_read_space(rb_out2disk) < sizeof(u_int32_t)) nanosleep(&req_time, &rem_time); rb_read(rb_out2disk, (char *)&driver_offset, sizeof(u_int32_t)); return sample_offset + driver_offset * src_ratio; } void send_meta(metadata_t * meta, void * data) { char send_cmd = CMD_METABLOCK; rb_write(rb_disk2gui, &send_cmd, 1); rb_write(rb_disk2gui, (char *)&meta, sizeof(metadata_t *)); } void * disk_thread(void * arg) { thread_info_t * info = (thread_info_t *)arg; file_decoder_t * fdec = NULL; u_int32_t playback_offset; /* amount of samples in the output driver buffer */ unsigned int n_read = 0; unsigned int want_read; int n_src = 0; int n_src_prev = 0; int end_of_file = 0; double src_ratio = 1.0; void * readbuf = malloc(MAX_RATIO * info->rb_size * 2 * sample_size); void * framebuf = malloc(MAX_RATIO * info->rb_size * 2 * sample_size); size_t n_space; char send_cmd, recv_cmd; char filename[RB_CONTROL_SIZE]; #ifdef HAVE_CDDA int flowthrough = 0; char filename_prev[RB_CONTROL_SIZE]; #endif /* HAVE_CDDA */ seek_t seek; cue_t cue; int i; #ifdef HAVE_SRC int src_type_prev; SRC_STATE * src_state; SRC_DATA src_data; int src_error; if ((src_state = src_new(options.src_type, 2, &src_error)) == NULL) { fprintf(stderr, "disk thread: error: src_new() failed: %s.\n", src_strerror(src_error)); exit(1); } src_type_prev = options.src_type; #endif /* HAVE_SRC */ if ((fdec = file_decoder_new()) == NULL) { fprintf(stderr, "disk thread: error: file_decoder_new() failed\n"); exit(1); } file_decoder_set_meta_cb(fdec, send_meta, NULL); if ((!readbuf) || (!framebuf)) { fprintf(stderr, "disk thread: malloc error\n"); exit(1); } AQUALUNG_MUTEX_LOCK(disk_thread_lock) filename[0] = '\0'; #ifdef HAVE_CDDA filename_prev[0] = '\0'; #endif /* HAVE_CDDA */ while (1) { recv_cmd = 0; if (rb_read_space(rb_gui2disk) > 0) { rb_read(rb_gui2disk, &recv_cmd, 1); switch (recv_cmd) { case CMD_CUE: /* read the string */ while (rb_read_space(rb_gui2disk) < sizeof(cue_t)) ; rb_read(rb_gui2disk, (void *)&cue, sizeof(cue_t)); #ifdef HAVE_CDDA strcpy(filename_prev, filename); #endif /* HAVE_CDDA */ if (cue.filename != NULL) { strncpy(filename, cue.filename, MAXLEN-1); free(cue.filename); } else { filename[0] = '\0'; } #ifdef HAVE_CDDA if (!flowthrough || !same_disc_next_track(filename, filename_prev)) { if (fdec->file_lib != 0) file_decoder_close(fdec); } #else if (fdec->file_lib != 0) file_decoder_close(fdec); #endif /* HAVE_CDDA */ if (filename[0] != '\0') { #ifdef HAVE_CDDA if (flowthrough && same_disc_next_track(filename, filename_prev) && (fdec->pdec != NULL)) { decoder_t * dec = (decoder_t *)fdec->pdec; cdda_decoder_reopen(dec, filename); fdec->samples_left = fdec->fileinfo.total_samples; file_decoder_set_rva(fdec, cue.voladj); fdec->sample_pos = 0; sample_offset = 0; send_cmd = CMD_FILEINFO; rb_write(rb_disk2gui, &send_cmd, sizeof(send_cmd)); rb_write(rb_disk2gui, (char *)&(fdec->fileinfo), sizeof(fileinfo_t)); info->is_streaming = 1; end_of_file = 0; } else { #endif /* HAVE_CDDA */ if (file_decoder_open(fdec, filename)) { fdec->samples_left = 0; info->is_streaming = 0; end_of_file = 1; send_cmd = CMD_FILEREQ; rb_write(rb_disk2gui, &send_cmd, 1); goto sleep; } else if (!sample_rates_ok(info->out_SR, fdec->fileinfo.sample_rate)) { fdec->file_open = 1; /* to get close_file() working */ file_decoder_close(fdec); fdec->file_open = 0; fdec->samples_left = 0; info->is_streaming = 0; end_of_file = 1; send_cmd = CMD_FILEREQ; rb_write(rb_disk2gui, &send_cmd, 1); goto sleep; } else { file_decoder_set_rva(fdec, cue.voladj); info->in_SR_prev = info->in_SR; info->in_SR = fdec->fileinfo.sample_rate; info->is_mono = fdec->fileinfo.is_mono; fdec->sample_pos = 0; #ifdef HAVE_CDDA if (fdec->file_lib == CDDA_LIB) { cdda_decoder_set_mode(((decoder_t *)fdec->pdec), options.cdda_drive_speed, options.cdda_paranoia_mode, options.cdda_paranoia_maxretries); } #endif /* HAVE_CDDA */ file_decoder_send_metadata(fdec); sample_offset = 0; send_cmd = CMD_FILEINFO; rb_write(rb_disk2gui, &send_cmd, sizeof(send_cmd)); rb_write(rb_disk2gui, (char *)&(fdec->fileinfo), sizeof(fileinfo_t)); info->is_streaming = 1; end_of_file = 0; } #ifdef HAVE_CDDA } flowthrough = 0; #endif /* HAVE_CDDA */ } else { /* STOP */ info->is_streaming = 0; /* send a FLUSH command to output thread to stop immediately */ flush_output(src_ratio); goto sleep; } break; case CMD_STOPWOFL: /* STOP but first flush output ringbuffer. */ info->is_streaming = 0; if (fdec->file_lib != 0) file_decoder_close(fdec); goto flush; break; case CMD_PAUSE: info->is_streaming = 0; /* send a FLUSH command to output thread */ playback_offset = flush_output(src_ratio); rollback(rb, fdec, src_ratio, playback_offset); if (fdec->is_stream) { file_decoder_pause(fdec); } break; case CMD_RESUME: info->is_streaming = 1; if (fdec->is_stream) { file_decoder_resume(fdec); } break; case CMD_FINISH: /* send FINISH to output thread, then goto exit */ send_cmd = CMD_FINISH; rb_write(rb_disk2out, &send_cmd, 1); goto done; break; case CMD_SEEKTO: while (rb_read_space(rb_gui2disk) < sizeof(seek_t)) ; rb_read(rb_gui2disk, (char *)&seek, sizeof(seek_t)); if (fdec->file_lib != 0) { file_decoder_seek(fdec, seek.seek_to_pos); /* send a FLUSH command to output thread */ flush_output(src_ratio); if (fdec->is_stream && !info->is_streaming) { file_decoder_pause(fdec); } } else { /* send dummy STATUS to gui, to set pos slider to zero */ disk_thread_status.samples_left = 0; disk_thread_status.sample_offset = 0; send_cmd = CMD_STATUS; rb_write(rb_disk2gui, &send_cmd, sizeof(send_cmd)); rb_write(rb_disk2gui, (char *)&disk_thread_status, sizeof(status_t)); } break; default: fprintf(stderr, "disk thread: received unexpected command %d\n", recv_cmd); break; } } else if (end_of_file) goto sleep; if (!info->is_streaming) goto sleep; n_read = 0; n_space = rb_write_space(rb) / (2 * sample_size); while (n_src < 0.95 * n_space) { src_ratio = (double)info->out_SR / (double)info->in_SR; n_src_prev = n_src; want_read = floor((n_space - n_src) / src_ratio); if (want_read == 0) break; if (want_read > MAX_RATIO * info->rb_size) want_read = MAX_RATIO * info->rb_size; n_read = file_decoder_read(fdec, readbuf, want_read); if (n_read < want_read) end_of_file = 1; if (info->is_mono) { /* convert to stereo interleaved */ for (i = 2*n_read - 1; i >= 0; i--) { memcpy(readbuf + i * sample_size, readbuf + i/2 * sample_size, sample_size); } } info->in_SR = fdec->fileinfo.sample_rate; if (info->in_SR == info->out_SR) { memcpy(framebuf + n_src_prev * 2*sample_size, readbuf, n_read * 2*sample_size); n_src += n_read; } else { /* do SRC */ #ifdef HAVE_SRC if ((info->in_SR_prev != info->in_SR) || (src_type_prev != options.src_type)) { /* reinit SRC */ src_state = src_delete(src_state); if ((src_state = src_new(options.src_type, 2, &src_error)) == NULL) { fprintf(stderr, "disk thread: error: src_new() failed: " "%s.\n", src_strerror(src_error)); goto done; } info->in_SR_prev = info->in_SR; src_type_prev = options.src_type; } src_data.input_frames = n_read; src_data.data_in = readbuf; src_data.src_ratio = src_ratio; src_data.data_out = framebuf + n_src_prev * 2*sample_size; src_data.output_frames = n_space - n_src_prev; src_data.end_of_input = 0; if ((src_error = src_process(src_state, &src_data))) { fprintf(stderr, "disk thread: SRC error: %s\n", src_strerror(src_error)); goto done; } n_src += src_data.output_frames_gen; #endif /* HAVE_SRC */ } if (end_of_file) { /* send request for a new filename */ #ifdef HAVE_CDDA flowthrough = 1; #endif /* HAVE_CDDA */ send_cmd = CMD_FILEREQ; rb_write(rb_disk2gui, &send_cmd, 1); goto sleep; } } flush: rb_write(rb, framebuf, n_src * 2*sample_size); /* update & send STATUS */ fdec->sample_pos += n_read; if (fdec->samples_left > n_read) fdec->samples_left -= n_read; sample_offset = rb_read_space(rb) / (2 * sample_size); disk_thread_status.sample_pos = fdec->sample_pos; disk_thread_status.samples_left = fdec->samples_left; disk_thread_status.sample_offset = sample_offset / src_ratio; disk_thread_status.sample_rate = info->in_SR; if (disk_thread_status.samples_left < 0) { disk_thread_status.samples_left = 0; } if (!rb_read_space(rb_gui2disk)) { send_cmd = CMD_STATUS; rb_write(rb_disk2gui, &send_cmd, sizeof(send_cmd)); rb_write(rb_disk2gui, (char *)&disk_thread_status, sizeof(status_t)); } /* cleanup buffer counters */ n_src = 0; n_src_prev = 0; end_of_file = 0; sleep: { /* suspend thread, wake up after 100 ms */ #ifdef _WIN32 GTimeVal time; GTimeVal * timeout = &time; g_get_current_time(timeout); g_time_val_add(timeout, 100000); #else struct timeval now; struct timezone tz; struct timespec timeout; gettimeofday(&now, &tz); timeout.tv_nsec = now.tv_usec * 1000 + 100000000; timeout.tv_sec = now.tv_sec; while (timeout.tv_nsec > 1000000000) { timeout.tv_nsec -= 1000000000; timeout.tv_sec += 1; } #endif /* _WIN32 */ AQUALUNG_COND_TIMEDWAIT(disk_thread_wake, disk_thread_lock, timeout) } } done: free(readbuf); free(framebuf); #ifdef HAVE_SRC src_state = src_delete(src_state); #endif /* HAVE_SRC */ file_decoder_delete(fdec); AQUALUNG_MUTEX_UNLOCK(disk_thread_lock) return 0; } /* SNDIO output thread */ #ifdef HAVE_SNDIO void * sndio_thread(void * arg) { u_int32_t i; thread_info_t * info = (thread_info_t *)arg; u_int32_t driver_offset = 0; int bufsize = 1024; int n_avail; size_t bytes_written; char recv_cmd; short * sndio_short_buf; struct sio_hdl * sndio_hdl; struct timespec req_time; struct timespec rem_time; req_time.tv_sec = 0; req_time.tv_nsec = 100000000; sndio_hdl = info->sndio_hdl; if ((info->sndio_short_buf = malloc(2*bufsize * sizeof(short))) == NULL) { fprintf(stderr, "sndio_thread: malloc error\n"); exit(1); } sndio_short_buf = info->sndio_short_buf; if ((l_buf = malloc(bufsize * sizeof(float))) == NULL) { fprintf(stderr, "sndio_thread: malloc error\n"); exit(1); } if ((r_buf = malloc(bufsize * sizeof(float))) == NULL) { fprintf(stderr, "sndio_thread: malloc error\n"); exit(1); } #ifdef HAVE_LADSPA ladspa_buflen = bufsize; #endif /* HAVE_LADSPA */ while (1) { sndio_wake: while (rb_read_space(rb_disk2out)) { rb_read(rb_disk2out, &recv_cmd, 1); switch (recv_cmd) { case CMD_FLUSH: while ((n_avail = rb_read_space(rb)) > 0) { if (n_avail > 2*bufsize * sizeof(short)) n_avail = 2*bufsize * sizeof(short); rb_read(rb, (char *)sndio_short_buf, 2*bufsize * sizeof(short)); } rb_write(rb_out2disk, (char *)&driver_offset, sizeof(u_int32_t)); goto sndio_wake; break; case CMD_FINISH: goto sndio_finish; break; default: fprintf(stderr, "sndio_thread: recv'd unknown command %d\n", recv_cmd); break; } } if ((n_avail = rb_read_space(rb) / (2*sample_size)) == 0) { nanosleep(&req_time, &rem_time); goto sndio_wake; } if (n_avail > bufsize) n_avail = bufsize; for (i = 0; i < n_avail; i++) { rb_read(rb, (char *)&(l_buf[i]), sample_size); rb_read(rb, (char *)&(r_buf[i]), sample_size); } #ifdef HAVE_LADSPA if (options.ladspa_is_postfader) { for (i = 0; i < n_avail; i++) { l_buf[i] *= left_gain; r_buf[i] *= right_gain; } } #else for (i = 0; i < n_avail; i++) { l_buf[i] *= left_gain; r_buf[i] *= right_gain; } #endif /* HAVE_LADSPA */ if (n_avail < bufsize) { for (i = n_avail; i < bufsize; i++) { l_buf[i] = 0.0f; r_buf[i] = 0.0f; } } /* plugin processing */ #ifdef HAVE_LADSPA plugin_lock = 1; for (i = 0; i < n_plugins; i++) { if (plugin_vect[i]->is_bypassed) continue; if (plugin_vect[i]->handle) { plugin_vect[i]->descriptor->run(plugin_vect[i]->handle, ladspa_buflen); } if (plugin_vect[i]->handle2) { plugin_vect[i]->descriptor->run(plugin_vect[i]->handle2, ladspa_buflen); } } plugin_lock = 0; if (!options.ladspa_is_postfader) { for (i = 0; i < bufsize; i++) { l_buf[i] *= left_gain; r_buf[i] *= right_gain; } } #endif /* HAVE_LADSPA */ for (i = 0; i < bufsize; i++) { if (l_buf[i] > 1.0) l_buf[i] = 1.0; else if (l_buf[i] < -1.0) l_buf[i] = -1.0; if (r_buf[i] > 1.0) r_buf[i] = 1.0; else if (r_buf[i] < -1.0) r_buf[i] = -1.0; sndio_short_buf[2*i] = floorf(32767.0 * l_buf[i]); sndio_short_buf[2*i+1] = floorf(32767.0 * r_buf[i]); } /* write data to audio device */ bytes_written = sio_write(sndio_hdl, sndio_short_buf, 2*n_avail * sizeof(short)); if (bytes_written != 2*n_avail * sizeof(short)) fprintf(stderr, "sndio_thread: Error writing to audio device\n"); } sndio_finish: return 0; } #endif /* HAVE_SNDIO */ /* PulseAudio output thread */ #ifdef HAVE_PULSE void * pulse_thread(void * arg) { u_int32_t i; thread_info_t * info = (thread_info_t *)arg; u_int32_t driver_offset = 0; int bufsize = 1024; int n_avail; int ret, err; char recv_cmd; pa_simple* pa = info->pa; short * pa_short_buf = NULL; struct timespec req_time; struct timespec rem_time; req_time.tv_sec = 0; req_time.tv_nsec = 100000000; if ((info->pa_short_buf = malloc(2*bufsize * sizeof(short))) == NULL) { fprintf(stderr, "pulse_thread: malloc error\n"); exit(1); } pa_short_buf = info->pa_short_buf; if ((l_buf = malloc(bufsize * sizeof(float))) == NULL) { fprintf(stderr, "pulse_thread: malloc error\n"); exit(1); } if ((r_buf = malloc(bufsize * sizeof(float))) == NULL) { fprintf(stderr, "pulse_thread: malloc error\n"); exit(1); } #ifdef HAVE_LADSPA ladspa_buflen = bufsize; #endif /* HAVE_LADSPA */ while (1) { pulse_wake: while (rb_read_space(rb_disk2out)) { rb_read(rb_disk2out, &recv_cmd, 1); switch (recv_cmd) { case CMD_FLUSH: while ((n_avail = rb_read_space(rb)) > 0) { if (n_avail > 2*bufsize * sizeof(short)) n_avail = 2*bufsize * sizeof(short); rb_read(rb, (char *)pa_short_buf, 2*bufsize * sizeof(short)); } rb_write(rb_out2disk, (char *)&driver_offset, sizeof(u_int32_t)); goto pulse_wake; break; case CMD_FINISH: goto pulse_finish; break; default: fprintf(stderr, "pulse_thread: recv'd unknown command %d\n", recv_cmd); break; } } if ((n_avail = rb_read_space(rb) / (2*sample_size)) == 0) { nanosleep(&req_time, &rem_time); goto pulse_wake; } if (n_avail > bufsize) n_avail = bufsize; for (i = 0; i < n_avail; i++) { rb_read(rb, (char *)&(l_buf[i]), sample_size); rb_read(rb, (char *)&(r_buf[i]), sample_size); } #ifdef HAVE_LADSPA if (options.ladspa_is_postfader) { for (i = 0; i < n_avail; i++) { l_buf[i] *= left_gain; r_buf[i] *= right_gain; } } #else for (i = 0; i < n_avail; i++) { l_buf[i] *= left_gain; r_buf[i] *= right_gain; } #endif /* HAVE_LADSPA */ if (n_avail < bufsize) { for (i = n_avail; i < bufsize; i++) { l_buf[i] = 0.0f; r_buf[i] = 0.0f; } } /* plugin processing */ #ifdef HAVE_LADSPA plugin_lock = 1; for (i = 0; i < n_plugins; i++) { if (plugin_vect[i]->is_bypassed) continue; if (plugin_vect[i]->handle) { plugin_vect[i]->descriptor->run(plugin_vect[i]->handle, ladspa_buflen); } if (plugin_vect[i]->handle2) { plugin_vect[i]->descriptor->run(plugin_vect[i]->handle2, ladspa_buflen); } } plugin_lock = 0; if (!options.ladspa_is_postfader) { for (i = 0; i < bufsize; i++) { l_buf[i] *= left_gain; r_buf[i] *= right_gain; } } #endif /* HAVE_LADSPA */ for (i = 0; i < bufsize; i++) { if (l_buf[i] > 1.0) l_buf[i] = 1.0; else if (l_buf[i] < -1.0) l_buf[i] = -1.0; if (r_buf[i] > 1.0) r_buf[i] = 1.0; else if (r_buf[i] < -1.0) r_buf[i] = -1.0; pa_short_buf[2*i] = floorf(32767.0 * l_buf[i]); pa_short_buf[2*i+1] = floorf(32767.0 * r_buf[i]); } /* write data to audio device */ ret = pa_simple_write(pa, pa_short_buf, 2*n_avail * sizeof(short), &err); if (ret != 0) fprintf(stderr, "pulse_thread: Error writing to audio device\n%s", pa_strerror(err)); } pulse_finish: return 0; } #endif /* HAVE_PULSE */ /* OSS output thread */ #ifdef HAVE_OSS void * oss_thread(void * arg) { u_int32_t i; thread_info_t * info = (thread_info_t *)arg; u_int32_t driver_offset = 0; int bufsize = 1024; int n_avail; int ioctl_status; char recv_cmd; int fd_oss = info->fd_oss; short * oss_short_buf; struct timespec req_time; struct timespec rem_time; req_time.tv_sec = 0; req_time.tv_nsec = 100000000; if ((info->oss_short_buf = malloc(2*bufsize * sizeof(short))) == NULL) { fprintf(stderr, "oss_thread: malloc error\n"); exit(1); } oss_short_buf = info->oss_short_buf; if ((l_buf = malloc(bufsize * sizeof(float))) == NULL) { fprintf(stderr, "oss_thread: malloc error\n"); exit(1); } if ((r_buf = malloc(bufsize * sizeof(float))) == NULL) { fprintf(stderr, "oss_thread: malloc error\n"); exit(1); } #ifdef HAVE_LADSPA ladspa_buflen = bufsize; #endif /* HAVE_LADSPA */ while (1) { oss_wake: while (rb_read_space(rb_disk2out)) { rb_read(rb_disk2out, &recv_cmd, 1); switch (recv_cmd) { case CMD_FLUSH: while ((n_avail = rb_read_space(rb)) > 0) { if (n_avail > 2*bufsize * sizeof(short)) n_avail = 2*bufsize * sizeof(short); rb_read(rb, (char *)oss_short_buf, 2*bufsize * sizeof(short)); } rb_write(rb_out2disk, (char *)&driver_offset, sizeof(u_int32_t)); goto oss_wake; break; case CMD_FINISH: goto oss_finish; break; default: fprintf(stderr, "oss_thread: recv'd unknown command %d\n", recv_cmd); break; } } if ((n_avail = rb_read_space(rb) / (2*sample_size)) == 0) { nanosleep(&req_time, &rem_time); goto oss_wake; } if (n_avail > bufsize) n_avail = bufsize; for (i = 0; i < n_avail; i++) { rb_read(rb, (char *)&(l_buf[i]), sample_size); rb_read(rb, (char *)&(r_buf[i]), sample_size); } #ifdef HAVE_LADSPA if (options.ladspa_is_postfader) { for (i = 0; i < n_avail; i++) { l_buf[i] *= left_gain; r_buf[i] *= right_gain; } } #else for (i = 0; i < n_avail; i++) { l_buf[i] *= left_gain; r_buf[i] *= right_gain; } #endif /* HAVE_LADSPA */ if (n_avail < bufsize) { for (i = n_avail; i < bufsize; i++) { l_buf[i] = 0.0f; r_buf[i] = 0.0f; } } /* plugin processing */ #ifdef HAVE_LADSPA plugin_lock = 1; for (i = 0; i < n_plugins; i++) { if (plugin_vect[i]->is_bypassed) continue; if (plugin_vect[i]->handle) { plugin_vect[i]->descriptor->run(plugin_vect[i]->handle, ladspa_buflen); } if (plugin_vect[i]->handle2) { plugin_vect[i]->descriptor->run(plugin_vect[i]->handle2, ladspa_buflen); } } plugin_lock = 0; if (!options.ladspa_is_postfader) { for (i = 0; i < bufsize; i++) { l_buf[i] *= left_gain; r_buf[i] *= right_gain; } } #endif /* HAVE_LADSPA */ for (i = 0; i < bufsize; i++) { if (l_buf[i] > 1.0) l_buf[i] = 1.0; else if (l_buf[i] < -1.0) l_buf[i] = -1.0; if (r_buf[i] > 1.0) r_buf[i] = 1.0; else if (r_buf[i] < -1.0) r_buf[i] = -1.0; oss_short_buf[2*i] = floorf(32767.0 * l_buf[i]); oss_short_buf[2*i+1] = floorf(32767.0 * r_buf[i]); } /* write data to audio device */ ioctl_status = write(fd_oss, oss_short_buf, 2*n_avail * sizeof(short)); if (ioctl_status != 2*n_avail * sizeof(short)) fprintf(stderr, "oss_thread: Error writing to audio device\n"); } oss_finish: return 0; } #endif /* HAVE_OSS */ /* ALSA output thread */ #ifdef HAVE_ALSA void * alsa_thread(void * arg) { u_int32_t i; u_int32_t driver_offset = 0; thread_info_t * info = (thread_info_t *)arg; snd_pcm_sframes_t n_written = 0; int bufsize = info->n_frames; int n_avail; char recv_cmd; int is_output_32bit = info->is_output_32bit; short * alsa_short_buf = NULL; int * alsa_int_buf = NULL; snd_pcm_t * pcm_handle = info->pcm_handle; struct timespec req_time; struct timespec rem_time; req_time.tv_sec = 0; req_time.tv_nsec = 100000000; if (is_output_32bit) { if ((info->alsa_int_buf = malloc(2*bufsize * sizeof(int))) == NULL) { fprintf(stderr, "alsa_thread: malloc error\n"); exit(1); } alsa_int_buf = info->alsa_int_buf; } else { if ((info->alsa_short_buf = malloc(2*bufsize * sizeof(short))) == NULL) { fprintf(stderr, "alsa_thread: malloc error\n"); exit(1); } alsa_short_buf = info->alsa_short_buf; } if ((l_buf = malloc(bufsize * sizeof(float))) == NULL) { fprintf(stderr, "alsa_thread: malloc error\n"); exit(1); } if ((r_buf = malloc(bufsize * sizeof(float))) == NULL) { fprintf(stderr, "alsa_thread: malloc error\n"); exit(1); } #ifdef HAVE_LADSPA ladspa_buflen = bufsize; #endif /* HAVE_LADSPA */ while (1) { alsa_wake: while (rb_read_space(rb_disk2out)) { rb_read(rb_disk2out, &recv_cmd, 1); switch (recv_cmd) { case CMD_FLUSH: if (is_output_32bit) { while ((n_avail = rb_read_space(rb)) > 0) { if (n_avail > 2*bufsize * sizeof(int)) n_avail = 2*bufsize * sizeof(int); rb_read(rb, (char *)alsa_int_buf, 2*bufsize * sizeof(int)); } } else { while ((n_avail = rb_read_space(rb)) > 0) { if (n_avail > 2*bufsize * sizeof(short)) n_avail = 2*bufsize * sizeof(short); rb_read(rb, (char *)alsa_short_buf, 2*bufsize * sizeof(short)); } } rb_write(rb_out2disk, (char *)&driver_offset, sizeof(u_int32_t)); goto alsa_wake; break; case CMD_FINISH: goto alsa_finish; break; default: fprintf(stderr, "alsa_thread: recv'd unknown command %d\n", recv_cmd); break; } } if ((n_avail = rb_read_space(rb) / (2*sample_size)) == 0) { nanosleep(&req_time, &rem_time); goto alsa_wake; } if (n_avail > bufsize) n_avail = bufsize; for (i = 0; i < n_avail; i++) { rb_read(rb, (char *)&(l_buf[i]), sample_size); rb_read(rb, (char *)&(r_buf[i]), sample_size); } #ifdef HAVE_LADSPA if (options.ladspa_is_postfader) { for (i = 0; i < n_avail; i++) { l_buf[i] *= left_gain; r_buf[i] *= right_gain; } } #else for (i = 0; i < n_avail; i++) { l_buf[i] *= left_gain; r_buf[i] *= right_gain; } #endif /* HAVE_LADSPA */ if (n_avail < bufsize) { for (i = n_avail; i < bufsize; i++) { l_buf[i] = 0.0f; r_buf[i] = 0.0f; } } /* plugin processing */ #ifdef HAVE_LADSPA plugin_lock = 1; for (i = 0; i < n_plugins; i++) { if (plugin_vect[i]->is_bypassed) continue; if (plugin_vect[i]->handle) { plugin_vect[i]->descriptor->run(plugin_vect[i]->handle, ladspa_buflen); } if (plugin_vect[i]->handle2) { plugin_vect[i]->descriptor->run(plugin_vect[i]->handle2, ladspa_buflen); } } plugin_lock = 0; if (!options.ladspa_is_postfader) { for (i = 0; i < bufsize; i++) { l_buf[i] *= left_gain; r_buf[i] *= right_gain; } } #endif /* HAVE_LADSPA */ if (is_output_32bit) { for (i = 0; i < bufsize; i++) { if (l_buf[i] > 1.0) l_buf[i] = 1.0; else if (l_buf[i] < -1.0) l_buf[i] = -1.0; if (r_buf[i] > 1.0) r_buf[i] = 1.0; else if (r_buf[i] < -1.0) r_buf[i] = -1.0; alsa_int_buf[2*i] = floorf(2147483647.0 * l_buf[i]); alsa_int_buf[2*i+1] = floorf(2147483647.0 * r_buf[i]); } /* write data to audio device */ if ((n_written = snd_pcm_writei(pcm_handle, alsa_int_buf, n_avail)) != n_avail) { snd_pcm_prepare(pcm_handle); } } else { for (i = 0; i < bufsize; i++) { if (l_buf[i] > 1.0) l_buf[i] = 1.0; else if (l_buf[i] < -1.0) l_buf[i] = -1.0; if (r_buf[i] > 1.0) r_buf[i] = 1.0; else if (r_buf[i] < -1.0) r_buf[i] = -1.0; alsa_short_buf[2*i] = floorf(32767.0 * l_buf[i]); alsa_short_buf[2*i+1] = floorf(32767.0 * r_buf[i]); } /* write data to audio device */ if ((n_written = snd_pcm_writei(pcm_handle, alsa_short_buf, n_avail)) != n_avail) { snd_pcm_prepare(pcm_handle); } } } alsa_finish: return 0; } #endif /* HAVE_ALSA */ /* JACK output function */ #ifdef HAVE_JACK int process(u_int32_t nframes, void * arg) { u_int32_t i; u_int32_t driver_offset = 0; u_int32_t n_avail; jack_default_audio_sample_t * out1 = jack_port_get_buffer(out_L_port, nframes); jack_default_audio_sample_t * out2 = jack_port_get_buffer(out_R_port, nframes); static int flushing = 0; static int flushcnt = 0; char recv_cmd; jack_nframes = nframes; #ifdef HAVE_LADSPA ladspa_buflen = nframes; #endif /* HAVE_LADSPA */ while (rb_read_space(rb_disk2out)) { rb_read(rb_disk2out, &recv_cmd, 1); switch (recv_cmd) { case CMD_FLUSH: flushing = 1; flushcnt = rb_read_space(rb)/nframes/ (2*sample_size) * 1.1f; rb_write(rb_out2disk, (char *)&driver_offset, sizeof(u_int32_t)); break; case CMD_FINISH: return 0; break; default: fprintf(stderr, "jack process(): recv'd unknown command %d\n", recv_cmd); break; } } n_avail = rb_read_space(rb) / (2*sample_size); if (n_avail > nframes) n_avail = nframes; for (i = 0; i < n_avail; i++) { rb_read(rb, (char *)&(l_buf[i]), sample_size); rb_read(rb, (char *)&(r_buf[i]), sample_size); } if (n_avail < nframes) { for (i = n_avail; i < nframes; i++) { l_buf[i] = 0.0f; r_buf[i] = 0.0f; } } if (flushing) { for (i = 0; i < n_avail; i++) { l_buf[i] = 0.0f; r_buf[i] = 0.0f; } } else { #ifdef HAVE_LADSPA if (options.ladspa_is_postfader) { for (i = 0; i < n_avail; i++) { l_buf[i] *= left_gain; r_buf[i] *= right_gain; } } #else for (i = 0; i < n_avail; i++) { l_buf[i] *= left_gain; r_buf[i] *= right_gain; } #endif /* HAVE_LADSPA */ /* plugin processing */ #ifdef HAVE_LADSPA if (n_avail > 0) { plugin_lock = 1; for (i = 0; i < n_plugins; i++) { if (plugin_vect[i]->is_bypassed) continue; if (plugin_vect[i]->handle) { plugin_vect[i]->descriptor->run(plugin_vect[i]->handle, ladspa_buflen); } if (plugin_vect[i]->handle2) { plugin_vect[i]->descriptor->run(plugin_vect[i]->handle2, ladspa_buflen); } } plugin_lock = 0; } if (!options.ladspa_is_postfader) { for (i = 0; i < nframes; i++) { l_buf[i] *= left_gain; r_buf[i] *= right_gain; } } #endif /* HAVE_LADSPA */ } for (i = 0; i < nframes; i++) { out1[i] = l_buf[i]; out2[i] = r_buf[i]; } if ((flushing) && (!rb_read_space(rb) || (--flushcnt == 0))) { flushing = 0; } return 0; } void jack_shutdown(void * arg) { jack_is_shutdown = 1; } #endif /* HAVE_JACK */ #ifndef _WIN32 int set_thread_priority(pthread_t thread, char * name, int realtime, int priority) { struct sched_param param; int policy; int x; if ((x = pthread_getschedparam(thread, &policy, ¶m)) != 0) { return -1; } if (realtime) { policy = SCHED_FIFO; #ifndef __OpenBSD__ if (priority == -1) { priority = 1; } #endif /* !__OpenBSD__ */ } if (priority != -1) { #ifdef PTHREAD_MIN_PRIORITY #ifdef PTHREAD_MAX_PRIORITY if (priority < PTHREAD_MIN_PRIORITY) { param.sched_priority = PTHREAD_MIN_PRIORITY; fprintf(stderr, "Warning: %s thread priority (%d) too low, set to %d", name, priority, PTHREAD_MIN_PRIORITY); } else if (priority > PTHREAD_MAX_PRIORITY) { param.sched_priority = PTHREAD_MAX_PRIORITY; fprintf(stderr, "Warning: %s thread priority (%d) too high, set to %d", name, priority, PTHREAD_MAX_PRIORITY); } else #endif /* PTHREAD_MAX_PRIORITY */ #endif /* PTHREAD_MIN_PRIORITY */ { param.sched_priority = priority; } } if ((x = pthread_setschedparam(thread, policy, ¶m)) != 0) { fprintf(stderr, "Warning: cannot use real-time scheduling for %s thread (%s/%d) " "(%d: %s)\n", name, policy == SCHED_FIFO ? "FIFO" : "RR", param.sched_priority, x, strerror(x)); } return x; } #endif /* _WIN32 */ #ifdef HAVE_SNDIO /* return values: * 0 : success * -1 : device busy * -N : unable to start with given params */ int sndio_init(thread_info_t * info, int verbose, int realtime, int priority) { struct sio_hdl * sndio_hdl; struct sio_par sndio_par; if (info->out_SR > MAX_SAMPLERATE) { if (verbose) { fprintf(stderr, "\nThe sample rate you set (%ld Hz) is higher than MAX_SAMPLERATE.\n", info->out_SR); fprintf(stderr, "This is an arbitrary limit, which you may safely enlarge " "if you really need to.\n"); fprintf(stderr, "Currently MAX_SAMPLERATE = %d Hz.\n", MAX_SAMPLERATE); } return -2; } sndio_hdl = sio_open(NULL, SIO_PLAY, 0); if (sndio_hdl == NULL) { if (verbose) { fprintf(stderr, "sio_open failed\n"); } return -1; } sio_initpar(&sndio_par); sndio_par.bits = 16; sndio_par.pchan = 2; sndio_par.rate = info->out_SR; sndio_par.sig = 1; sndio_par.le = 1; sndio_par.round = sndio_par.rate/8; sndio_par.appbufsz = sndio_par.round*2; if(sio_setpar(sndio_hdl, &sndio_par) == 0) { if (verbose) { fprintf(stderr, "sio_setpar failed\n"); } sio_close(sndio_hdl); return -3; } if(sio_getpar(sndio_hdl, &sndio_par) == 0) { if (verbose) { fprintf(stderr, "sio_getpar failed\n"); } sio_close(sndio_hdl); return -4; } if((sndio_par.bits != 16) || (sndio_par.pchan != 2) || \ (sndio_par.rate != info->out_SR) || (sndio_par.sig != 1) || \ (sndio_par.le != 1)) { if (verbose) { fprintf(stderr, "can't set sndio parameters\n"); } sio_close(sndio_hdl); return -5; } if(sio_start(sndio_hdl) == 0) { if (verbose) { fprintf(stderr, "sio_start failed\n"); } sio_close(sndio_hdl); return -3; } info->sndio_hdl = sndio_hdl; AQUALUNG_THREAD_CREATE(info->sndio_thread_id, NULL, sndio_thread, info) set_thread_priority(info->sndio_thread_id, "sndio output", realtime, priority); return 0; } #endif /* HAVE_SNDIO */ #ifdef HAVE_OSS /* return values: * 0 : success * -1 : device busy * -N : unable to start with given params */ int oss_init(thread_info_t * info, int verbose, int realtime, int priority) { int ioctl_arg; int ioctl_status; if (info->out_SR > MAX_SAMPLERATE) { if (verbose) { fprintf(stderr, "\nThe sample rate you set (%ld Hz) is higher than MAX_SAMPLERATE.\n", info->out_SR); fprintf(stderr, "This is an arbitrary limit, which you may safely enlarge " "if you really need to.\n"); fprintf(stderr, "Currently MAX_SAMPLERATE = %d Hz.\n", MAX_SAMPLERATE); } return -2; } /* open dsp device */ info->fd_oss = open(device_name, O_WRONLY, 0); if (info->fd_oss < 0) { if (verbose) { fprintf(stderr, "oss_init: open of %s ", device_name); perror("failed"); } return -1; } ioctl_arg = 16; /* bitdepth */ ioctl_status = ioctl(info->fd_oss, SOUND_PCM_WRITE_BITS, &ioctl_arg); if (ioctl_status == -1) { if (verbose) { perror("oss_init: SOUND_PCM_WRITE_BITS ioctl failed"); } return -3; } if (ioctl_arg != 16) { if (verbose) { perror("oss_init: unable to set sample size"); } return -4; } ioctl_arg = 2; /* stereo */ ioctl_status = ioctl(info->fd_oss, SOUND_PCM_WRITE_CHANNELS, &ioctl_arg); if (ioctl_status == -1) { if (verbose) { perror("oss_init: SOUND_PCM_WRITE_CHANNELS ioctl failed"); } return -5; } if (ioctl_arg != 2) { if (verbose) { perror("oss_init: unable to set number of channels"); } return -6; } ioctl_arg = info->out_SR; ioctl_status = ioctl(info->fd_oss, SOUND_PCM_WRITE_RATE, &ioctl_arg); if (ioctl_status == -1) { if (verbose) { perror("oss_init: SOUND_PCM_WRITE_RATE ioctl failed"); } return -7; } if (ioctl_arg != info->out_SR) { if (verbose) { fprintf(stderr, "oss_init: unable to set sample_rate to %ld\n", info->out_SR); } return -8; } /* start OSS output thread */ AQUALUNG_THREAD_CREATE(info->oss_thread_id, NULL, oss_thread, info) set_thread_priority(info->oss_thread_id, "OSS output", realtime, priority); return 0; } #endif /* HAVE_OSS */ #ifdef HAVE_ALSA /* return values: * 0 : success * -1 : device busy * -N : unable to start with given params */ int alsa_init(thread_info_t * info, int verbose) { unsigned rate; int dir = 0; int ret; ret = snd_pcm_open(&info->pcm_handle, info->pcm_name, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK); if (ret < 0) { if (verbose) { fprintf(stderr, "alsa_init: error opening PCM device %s: %s\n", info->pcm_name, snd_strerror(ret)); } return -1; } snd_pcm_close(info->pcm_handle); /* now that we know the device is available, open it in blocking mode */ /* this is not deadlock safe. */ ret = snd_pcm_open(&info->pcm_handle, info->pcm_name, SND_PCM_STREAM_PLAYBACK, 0); if (ret < 0) { if (verbose) { fprintf(stderr, "alsa_init: error reopening PCM device %s: %s\n", info->pcm_name, snd_strerror(ret)); } return -2; } snd_pcm_hw_params_alloca(&info->hwparams); if (snd_pcm_hw_params_any(info->pcm_handle, info->hwparams) < 0) { if (verbose) { fprintf(stderr, "alsa_init: cannot configure this PCM device.\n"); } return -3; } if (snd_pcm_hw_params_set_periods_integer(info->pcm_handle, info->hwparams) < 0) { fprintf(stderr, "alsa_init warning: cannot restrict period size to integer value.\n"); } if (snd_pcm_hw_params_set_access(info->pcm_handle, info->hwparams, SND_PCM_ACCESS_RW_INTERLEAVED) < 0) { if (verbose) { fprintf(stderr, "alsa_init: error setting access to SND_PCM_ACCESS_RW_INTERLEAVED.\n"); } return -4; } info->is_output_32bit = 1; if (snd_pcm_hw_params_set_format(info->pcm_handle, info->hwparams, SND_PCM_FORMAT_S32) < 0) { if (verbose) { fprintf(stderr, "alsa_init: unable to open 32 bit output, falling back to 16 bit...\n"); } if (snd_pcm_hw_params_set_format(info->pcm_handle, info->hwparams, SND_PCM_FORMAT_S16) < 0) { if (verbose) { fprintf(stderr, "alsa_init: unable to open 16 bit output, exiting.\n"); } return -5; } info->is_output_32bit = 0; } rate = info->out_SR; dir = 0; if (snd_pcm_hw_params_set_rate_near(info->pcm_handle, info->hwparams, &rate, &dir) < 0) { if (verbose) { fprintf(stderr, "alsa_init: can't set sample rate to %u.\n", rate); } return -6; } if (rate != info->out_SR) { if (verbose) { fprintf(stderr, "Requested sample rate (%ld Hz) cannot be set, ", info->out_SR); fprintf(stderr, "using closest available rate (%d Hz).\n", rate); } info->out_SR = rate; } if (snd_pcm_hw_params_set_channels(info->pcm_handle, info->hwparams, 2) < 0) { if (verbose) { fprintf(stderr, "alsa_init: error setting channels.\n"); } return -7; } info->n_frames = 512; if (snd_pcm_hw_params_set_period_size_near(info->pcm_handle, info->hwparams, &info->n_frames, NULL) < 0) { if (verbose) { fprintf(stderr, "alsa_init warning: error setting period size\n"); } } if (snd_pcm_hw_params(info->pcm_handle, info->hwparams) < 0) { if (verbose) { fprintf(stderr, "alsa_init: error setting HW params.\n"); } return -8; } return 0; } #endif /* HAVE_ALSA */ #ifdef HAVE_JACK /* return values: * 0 : success * -1 : couldn't connect to Jack * -N : Jack sample rate (N) out of range */ int jack_init(thread_info_t * info) { if (client_name == NULL) client_name = strdup("aqualung"); if ((jack_client = jack_client_new(client_name)) == 0) { return -1; } jack_set_process_callback(jack_client, process, info); jack_on_shutdown(jack_client, jack_shutdown, info); if ((info->out_SR = jack_get_sample_rate(jack_client)) > MAX_SAMPLERATE) { jack_client_close(jack_client); return -info->out_SR; } out_L_port = jack_port_register(jack_client, "out_L", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); out_R_port = jack_port_register(jack_client, "out_R", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); jack_nframes = jack_get_buffer_size(jack_client); if ((l_buf = malloc(jack_nframes * sizeof(float))) == NULL) { fprintf(stderr, "jack_init: malloc error\n"); exit(1); } if ((r_buf = malloc(jack_nframes * sizeof(float))) == NULL) { fprintf(stderr, "jack_init: malloc error\n"); exit(1); } #ifdef HAVE_LADSPA ladspa_buflen = jack_nframes; #endif /* HAVE_LADSPA */ return 0; } void jack_client_start(void) { const char ** ports_out; if (jack_activate(jack_client)) { fprintf(stderr, "Cannot activate JACK client.\n"); exit(1); } if (auto_connect) { if (default_ports) { if ((ports_out = jack_get_ports(jack_client, NULL, NULL, JackPortIsPhysical|JackPortIsInput)) == NULL) { fprintf(stderr, "Cannot find any physical playback ports.\n"); } else { if (jack_connect(jack_client, jack_port_name(out_L_port), ports_out[0])) { fprintf(stderr, "Cannot connect out_L port to %s.\n", ports_out[0]); } else { fprintf(stderr, "Connected out_L to %s\n", ports_out[0]); } if (jack_connect(jack_client, jack_port_name(out_R_port), ports_out[1])) { fprintf(stderr, "Cannot connect out_R port to %s.\n", ports_out[1]); } else { fprintf(stderr, "Connected out_R to %s\n", ports_out[1]); } free(ports_out); } } else { if (jack_connect(jack_client, jack_port_name(out_L_port), user_port1)) { fprintf(stderr, "Cannot connect out_L port to %s.\n", user_port1); } else { fprintf(stderr, "Connected out_L to %s\n", user_port1); } if (jack_connect(jack_client, jack_port_name(out_R_port), user_port2)) { fprintf(stderr, "Cannot connect out_R port to %s.\n", user_port2); } else { fprintf(stderr, "Connected out_R to %s\n", user_port2); } } } } #endif /* HAVE_JACK */ #ifdef HAVE_PULSE /* return values: * 0 : success * -1: sample rate out of range * +N: unable to initilize PulseAudio * N = error code returned by PulseAudio. */ int pulse_init(thread_info_t * info, int verbose, int realtime, int priority) { int err = 0; if (info->out_SR > MAX_SAMPLERATE) { if (verbose) { fprintf(stderr, "\nThe sample rate you set (%ld Hz) is higher than MAX_SAMPLERATE.\n", info->out_SR); fprintf(stderr, "This is an arbitrary limit, which you may safely enlarge " "if you really need to.\n"); fprintf(stderr, "Currently MAX_SAMPLERATE = %d Hz.\n", MAX_SAMPLERATE); } return -1; } info->pa_spec.format = PA_SAMPLE_S16NE; info->pa_spec.channels = 2; info->pa_spec.rate = info->out_SR; info->pa = pa_simple_new(NULL, "Aqualung", PA_STREAM_PLAYBACK, NULL, "Music", &info->pa_spec, NULL, NULL, &err); if (!info->pa) { if (verbose) { fprintf(stderr, "Unable to initilize PulseAudio: %s\n", pa_strerror(err)); } return err; } /* start PulseAudio output thread */ AQUALUNG_THREAD_CREATE(info->pulse_thread_id, NULL, pulse_thread, info) set_thread_priority(info->pulse_thread_id, "PulseAudio output", realtime, priority); return 0; } #endif /* HAVE_PULSE */ #ifdef _WIN32 #define WIN32_BUFFER_LEN (1<<16) void * win32_thread(void * arg) { u_int32_t i; u_int32_t driver_offset = 0; thread_info_t * info = (thread_info_t *)arg; WAVEFORMATEX wf; MMRESULT error; HWAVEOUT hwave; short * short_buf = NULL; int nbufs = 8; int bufcnt; WAVEHDR whdr[nbufs]; int j; int n_avail; char recv_cmd; MMTIME mmtime; DWORD samples_sent = 0; int bufsize = WIN32_BUFFER_LEN / sizeof(short) / nbufs / 2; if ((l_buf = calloc(1, bufsize * sizeof(float))) == NULL) { fprintf(stderr, "win32_thread: malloc error\n"); exit(1); } if ((r_buf = calloc(1, bufsize * sizeof(float))) == NULL) { fprintf(stderr, "win32_thread: malloc error\n"); exit(1); } #ifdef HAVE_LADSPA ladspa_buflen = bufsize; #endif /* HAVE_LADSPA */ if ((short_buf = calloc(1, WIN32_BUFFER_LEN)) == NULL) { fprintf(stderr, "win32_thread: malloc error\n"); exit(1); } wf.nChannels = 2; wf.nSamplesPerSec = info->out_SR; wf.nBlockAlign = 2 * sizeof(short); wf.wFormatTag = WAVE_FORMAT_PCM; wf.cbSize = 0; wf.wBitsPerSample = 16; wf.nAvgBytesPerSec = wf.nBlockAlign * wf.nSamplesPerSec; error = waveOutOpen(&hwave, WAVE_MAPPER, &wf, 0L, 0L, 0L); if (error != MMSYSERR_NOERROR) { printf("waveOutOpen failed, error = %d\n", error); switch (error) { case MMSYSERR_ALLOCATED: puts("MMSYSERR_ALLOCATED"); break; case MMSYSERR_BADDEVICEID: puts("MMSYSERR_BADDEVICEID"); break; case MMSYSERR_NODRIVER: puts("MMSYSERR_NODRIVER"); break; case MMSYSERR_NOMEM: puts("MMSYSERR_NOMEM"); break; case WAVERR_BADFORMAT: puts("WAVERR_BADFORMAT"); break; case WAVERR_SYNC: puts("WAVERR_SYNC"); break; } return NULL; } for (bufcnt = 0; bufcnt < nbufs; bufcnt++) { whdr[bufcnt].lpData = (char *)short_buf + bufcnt * WIN32_BUFFER_LEN / nbufs; whdr[bufcnt].dwBufferLength = WIN32_BUFFER_LEN / nbufs; whdr[bufcnt].dwUser = 0L; whdr[bufcnt].dwFlags = 0L; whdr[bufcnt].dwLoops = 0L; if ((error = waveOutPrepareHeader(hwave, &(whdr[bufcnt]), sizeof(WAVEHDR))) != MMSYSERR_NOERROR) { printf("waveOutPrepareHeader[%d] failed : %08X\n", bufcnt, error); waveOutUnprepareHeader(hwave, &(whdr[bufcnt]), sizeof(WAVEHDR)); waveOutClose(hwave); return NULL; } } for (j = 0; j < WIN32_BUFFER_LEN / sizeof(short); j++) { short_buf[j] = 0; } for (bufcnt = 0; bufcnt < nbufs; bufcnt++) { if ((error = waveOutWrite(hwave, &(whdr[bufcnt]), sizeof(WAVEHDR))) != MMSYSERR_NOERROR) { printf("waveOutWrite[%d] failed : %08X\n", bufcnt, error); waveOutUnprepareHeader(hwave, &(whdr[bufcnt]), sizeof(WAVEHDR)); waveOutClose(hwave); return NULL; } samples_sent += bufsize; } bufcnt = 0; while (1) { win32_wake: mmtime.wType = TIME_SAMPLES; if ((error = waveOutGetPosition(hwave, &mmtime, sizeof(MMTIME))) != MMSYSERR_NOERROR) { printf("waveOutGetPosition failed : %08X\n", error); return NULL; } driver_offset = samples_sent - mmtime.u.sample; while (rb_read_space(rb_disk2out)) { rb_read(rb_disk2out, &recv_cmd, 1); switch (recv_cmd) { case CMD_FLUSH: while ((n_avail = rb_read_space(rb)) > 0) { if (n_avail > 2*bufsize * sizeof(short)) n_avail = 2*bufsize * sizeof(short); rb_read(rb, (char *)short_buf, 2*bufsize * sizeof(short)); } for (j = 0; j < WIN32_BUFFER_LEN / sizeof(short); j++) { short_buf[j] = 0; } rb_write(rb_out2disk, (char *)&driver_offset, sizeof(u_int32_t)); goto win32_wake; break; case CMD_FINISH: goto win32_finish; break; default: fprintf(stderr, "win32_thread: recv'd unknown command %d\n", recv_cmd); break; } } if ((n_avail = rb_read_space(rb) / (2*sample_size)) == 0) { Sleep(100); goto win32_wake; } if (n_avail > bufsize) n_avail = bufsize; for (i = 0; i < n_avail; i++) { rb_read(rb, (char *)&(l_buf[i]), sample_size); rb_read(rb, (char *)&(r_buf[i]), sample_size); } #ifdef HAVE_LADSPA if (options.ladspa_is_postfader) { for (i = 0; i < n_avail; i++) { l_buf[i] *= left_gain; r_buf[i] *= right_gain; } } #else for (i = 0; i < n_avail; i++) { l_buf[i] *= left_gain; r_buf[i] *= right_gain; } #endif /* HAVE_LADSPA */ if (n_avail < bufsize) { for (i = n_avail; i < bufsize; i++) { l_buf[i] = 0.0f; r_buf[i] = 0.0f; } } /* plugin processing */ #ifdef HAVE_LADSPA plugin_lock = 1; for (i = 0; i < n_plugins; i++) { if (plugin_vect[i]->is_bypassed) continue; if (plugin_vect[i]->handle) { plugin_vect[i]->descriptor->run(plugin_vect[i]->handle, ladspa_buflen); } if (plugin_vect[i]->handle2) { plugin_vect[i]->descriptor->run(plugin_vect[i]->handle2, ladspa_buflen); } } plugin_lock = 0; if (!options.ladspa_is_postfader) { for (i = 0; i < bufsize; i++) { l_buf[i] *= left_gain; r_buf[i] *= right_gain; } } #endif /* HAVE_LADSPA */ while (!(whdr[bufcnt].dwFlags & WHDR_DONE)) Sleep(1); for (i = 0; i < bufsize; i++) { if (l_buf[i] > 1.0) l_buf[i] = 1.0; else if (l_buf[i] < -1.0) l_buf[i] = -1.0; if (r_buf[i] > 1.0) r_buf[i] = 1.0; else if (r_buf[i] < -1.0) r_buf[i] = -1.0; short_buf[2*bufcnt*bufsize + 2*i] = floorf(32767.0 * l_buf[i]); short_buf[2*bufcnt*bufsize + 2*i+1] = floorf(32767.0 * r_buf[i]); } /* write data to audio device */ if ((error = waveOutWrite(hwave, &(whdr[bufcnt]), sizeof(WAVEHDR))) != MMSYSERR_NOERROR) { printf("waveOutWrite[%d] failed : %08X\n", bufcnt, error); waveOutUnprepareHeader(hwave, &(whdr[bufcnt]), sizeof(WAVEHDR)); waveOutClose(hwave); return NULL; } samples_sent += bufsize; ++bufcnt; if (bufcnt == nbufs) bufcnt = 0; } win32_finish: waveOutPause(hwave); waveOutReset(hwave); for (bufcnt = 0; bufcnt < nbufs; bufcnt++) { waveOutUnprepareHeader(hwave, &(whdr[bufcnt]), sizeof(WAVEHDR)); } waveOutClose(hwave); return 0; } #endif /* _WIN32 */ void load_default_cl(int * argc, char *** argv) { int i = 0; xmlDocPtr doc; xmlNodePtr cur; xmlNodePtr root; xmlChar * key; FILE * f; char config_file[MAXLEN]; char default_param[MAXLEN]; char cl[MAXLEN]; int ret; if ((ret = chdir(options.confdir)) != 0) { if (errno == ENOENT) { fprintf(stderr, "Creating directory %s\n", options.confdir); if (mkdir(options.confdir, S_IRUSR | S_IWUSR | S_IXUSR) < 0) { fprintf(stderr, "fatal error: cannot create config directory.\n"); fprintf(stderr, "mkdir: %s\n", strerror(errno)); exit(1); } else { chdir(options.confdir); } } else { fprintf(stderr, "An error occured while attempting chdir(\"%s\"). errno = %d\n", options.confdir, errno); } } sprintf(config_file, "%s/config.xml", options.confdir); if ((f = fopen(config_file, "rt")) == NULL) { fprintf(stderr, "No config.xml -- creating empty one: %s\n", config_file); fprintf(stderr, "Wired-in defaults will be used.\n"); doc = xmlNewDoc((const xmlChar *) "1.0"); root = xmlNewNode(NULL, (const xmlChar *) "aqualung_config"); xmlDocSetRootElement(doc, root); xmlSaveFormatFile(config_file, doc, 1); xmlFreeDoc(doc); *argc = 1; return; } fclose(f); doc = xmlParseFile(config_file); if (doc == NULL) { fprintf(stderr, "An XML error occured while parsing %s\n", config_file); return; } cur = xmlDocGetRootElement(doc); if (cur == NULL) { fprintf(stderr, "load_config: empty XML document\n"); xmlFreeDoc(doc); return; } if (xmlStrcmp(cur->name, (const xmlChar *)"aqualung_config")) { fprintf(stderr, "load_config: XML document of the wrong type, " "root node != aqualung_config\n"); xmlFreeDoc(doc); return; } default_param[0] = '\0'; cur = cur->xmlChildrenNode; while (cur != NULL) { if ((!xmlStrcmp(cur->name, (const xmlChar *)"default_param"))) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); if (key != NULL) strncpy(default_param, (char *) key, MAXLEN-1); xmlFree(key); } cur = cur->next; } xmlFreeDoc(doc); snprintf(cl, MAXLEN-1, "aqualung %s", default_param); while (cl[i] != '\0') { ++(*argc); if ((*argv = realloc(*argv, *argc * sizeof(char *))) == NULL) { fprintf(stderr, "realloc() failed in load_default_cl()\n"); exit(1); } (*argv)[*argc-1] = cl+i; while ((cl[i] != ' ') && (cl[i] != '\0')) ++i; if (cl[i] == ' ') cl[i++] = '\0'; } if ((*argv = realloc(*argv, (*argc+1) * sizeof(char *))) == NULL) { fprintf(stderr, "realloc() failed in load_default_cl()\n"); exit(1); } (*argv)[*argc] = NULL; return; } void print_info(void) { fprintf(stderr, "Aqualung -- Music player for GNU/Linux\n"); fprintf(stderr, "Build version: %s\n", AQUALUNG_VERSION); fprintf(stderr, "(C) 2004-2010 Tom Szilagyi \n" "This is free software, and you are welcome to redistribute it\n" "under certain conditions; see the file COPYING for details.\n"); } #define V_YES " [+] " #define V_NO " [ ] " void print_version(void) { print_info(); fprintf(stderr, "\nThis Aqualung binary is compiled with:\n"); fprintf(stderr, "\n Optional features:\n"); #ifdef HAVE_LADSPA fprintf(stderr, V_YES); #else fprintf(stderr, V_NO); #endif /* HAVE_LADSPA */ fprintf(stderr, "LADSPA plugin support\n"); #ifdef HAVE_CDDA fprintf(stderr, V_YES); #else fprintf(stderr, V_NO); #endif /* HAVE_CDDA */ fprintf(stderr, "CDDA (Audio CD) support\n"); #ifdef HAVE_CDDB fprintf(stderr, V_YES); #else fprintf(stderr, V_NO); #endif /* HAVE_CDDB */ fprintf(stderr, "CDDB support\n"); #ifdef HAVE_SRC fprintf(stderr, V_YES); #else fprintf(stderr, V_NO); #endif /* HAVE_SRC */ fprintf(stderr, "Sample Rate Converter support\n"); #ifdef HAVE_IFP fprintf(stderr, V_YES); #else fprintf(stderr, V_NO); #endif /* HAVE_IFP */ fprintf(stderr, "iRiver iFP driver support\n"); #ifdef HAVE_LOOP fprintf(stderr, V_YES); #else fprintf(stderr, V_NO); #endif /* HAVE_LOOP */ fprintf(stderr, "Loop playback support\n"); #ifdef HAVE_SYSTRAY fprintf(stderr, V_YES); #else fprintf(stderr, V_NO); #endif /* HAVE_SYSTRAY */ fprintf(stderr, "Systray support\n"); #ifdef HAVE_PODCAST fprintf(stderr, V_YES); #else fprintf(stderr, V_NO); #endif /* HAVE_PODCAST */ fprintf(stderr, "Podcast support\n"); #ifdef HAVE_LUA fprintf(stderr, V_YES); #else fprintf(stderr, V_NO); #endif /* HAVE_LUA */ fprintf(stderr, "Lua (programmable title formatting) support\n"); fprintf(stderr, "\n Decoding support:\n"); #ifdef HAVE_SNDFILE fprintf(stderr, V_YES); #else fprintf(stderr, V_NO); #endif /* HAVE_SNDFILE */ fprintf(stderr, "sndfile (WAV, AIFF, etc.)\n"); #ifdef HAVE_FLAC fprintf(stderr, V_YES); #else fprintf(stderr, V_NO); #endif /* HAVE_FLAC */ fprintf(stderr, "Free Lossless Audio Codec (FLAC)\n"); #ifdef HAVE_OGG_VORBIS fprintf(stderr, V_YES); #else fprintf(stderr, V_NO); #endif /* HAVE_OGG_VORBIS */ fprintf(stderr, "Ogg Vorbis\n"); #ifdef HAVE_SPEEX fprintf(stderr, V_YES); #else fprintf(stderr, V_NO); #endif /* HAVE_SPEEX */ fprintf(stderr, "Ogg Speex\n"); #ifdef HAVE_MPEG fprintf(stderr, V_YES); #else fprintf(stderr, V_NO); #endif /* HAVE_MPEG */ fprintf(stderr, "MPEG Audio (MPEG 1-2.5 Layer I-III)\n"); #ifdef HAVE_MOD fprintf(stderr, V_YES); #else fprintf(stderr, V_NO); #endif /* HAVE_MOD */ fprintf(stderr, "MOD Audio (MOD, S3M, XM, IT, etc.)\n"); #ifdef HAVE_MPC fprintf(stderr, V_YES); #else fprintf(stderr, V_NO); #endif /* HAVE_MPC */ fprintf(stderr, "Musepack\n"); #ifdef HAVE_MAC fprintf(stderr, V_YES); #else fprintf(stderr, V_NO); #endif /* HAVE_MAC */ fprintf(stderr, "Monkey's Audio Codec\n"); #ifdef HAVE_WAVPACK fprintf(stderr, V_YES); #else fprintf(stderr, V_NO); #endif /* HAVE_WAVPACK */ fprintf(stderr, "WavPack\n"); #ifdef HAVE_LAVC fprintf(stderr, V_YES); #else fprintf(stderr, V_NO); #endif /* HAVE_LAVC */ fprintf(stderr, "LAVC (AC3, AAC, WavPack, WMA, etc.)\n"); fprintf(stderr, "\n Encoding support:\n"); #ifdef HAVE_SNDFILE fprintf(stderr, V_YES); #else fprintf(stderr, V_NO); #endif /* HAVE_SNDFILE */ fprintf(stderr, "sndfile (WAV)\n"); #ifdef HAVE_FLAC fprintf(stderr, V_YES); #else fprintf(stderr, V_NO); #endif /* HAVE_FLAC */ fprintf(stderr, "Free Lossless Audio Codec (FLAC)\n"); #ifdef HAVE_VORBISENC fprintf(stderr, V_YES); #else fprintf(stderr, V_NO); #endif /* HAVE_VORBISENC */ fprintf(stderr, "Ogg Vorbis\n"); #ifdef HAVE_LAME fprintf(stderr, V_YES); #else fprintf(stderr, V_NO); #endif /* HAVE_LAME */ fprintf(stderr, "LAME (MP3)\n"); fprintf(stderr, "\n Output driver support:\n"); #ifdef HAVE_SNDIO fprintf(stderr, V_YES); #else fprintf(stderr, V_NO); #endif /* HAVE_SNDIO */ fprintf(stderr, "sndio Audio\n"); #ifdef HAVE_OSS fprintf(stderr, V_YES); #else fprintf(stderr, V_NO); #endif /* HAVE_OSS */ fprintf(stderr, "OSS Audio\n"); #ifdef HAVE_ALSA fprintf(stderr, V_YES); #else fprintf(stderr, V_NO); #endif /* HAVE_ALSA */ fprintf(stderr, "ALSA Audio\n"); #ifdef HAVE_JACK fprintf(stderr, V_YES); #else fprintf(stderr, V_NO); #endif /* HAVE_JACK */ fprintf(stderr, "JACK Audio Server\n"); #ifdef HAVE_PULSE fprintf(stderr, V_YES); #else fprintf(stderr, V_NO); #endif /* HAVE_PULSE */ fprintf(stderr, "PulseAudio\n"); #ifdef _WIN32 fprintf(stderr, V_YES); #else fprintf(stderr, V_NO); #endif /* _WIN32 */ fprintf(stderr, "Win32 Sound API\n"); fprintf(stderr, "\n"); } void print_usage(void) { print_info(); fprintf(stderr, "\nInvocation:\n" "aqualung --help\n" "aqualung --version\n" "aqualung [--output (oss|alsa|jack|sndio|pulse|win32)] [options] [file1 [file2 ...]]\n" "\nGeneral options:\n" "-D, --disk-realtime: Try to use realtime (SCHED_FIFO) scheduling for disk thread.\n" "-Y, --disk-priority : When running -D, set scheduler priority to (defaults to 1).\n" "\nOptions relevant to ALSA output:\n" "-d, --device : Set the output device (defaults to 'default').\n" "-r, --rate : Set the output sample rate.\n" "-R, --realtime: Try to use realtime (SCHED_FIFO) scheduling for ALSA output thread.\n" "-P, --priority : Set scheduler priority to (default is 1 when -R is used).\n" "\nOptions relevant to OSS output:\n" "-d, --device : Set the output device (defaults to '" OSS_DEVICE "').\n" "-r, --rate : Set the output sample rate.\n" "-R, --realtime: Try to use realtime (SCHED_FIFO) scheduling for OSS output thread.\n" "-P, --priority : Set scheduler priority to (default is 1 when -R is used).\n" "\nOptions relevant to JACK output:\n" "-a[,], --auto[=,]: Auto-connect output ports to\n" "given JACK ports (defaults to first two hardware playback ports).\n" "-c, --client : Set client name (needed if you want to run multiple instances of the program).\n" "\nOptions relevant to PulseAudio and sndio outputs:\n" "-r, --rate : Set the output sample rate.\n" "-R, --realtime: Try to use realtime (SCHED_FIFO) scheduling for audio output thread.\n" "-P, --priority : Set scheduler priority to (default is 1 when -R is used).\n" "\nOptions relevant to WIN32 output:\n" "-r, --rate : Set the output sample rate.\n" "\nOptions relevant to the Sample Rate Converter:\n" "-s[], --srctype[=]: Choose the SRC type, or print the list of available\n" "types if no number given. The default is SRC type 4 (Linear Interpolator).\n" "\nOptions for remote cue control:\n" "-N, --session : Number of Aqualung instance to control.\n" "-B, --back: Jump to previous track.\n" "-F, --fwd: Jump to next track.\n" "-L, --play: Start playing.\n" "-U, --pause: Pause playback, or resume if already paused.\n" "-T, --stop: Stop playback.\n" "-V, --volume [m|M]|[=]: Set, adjust or mute volume.\n" "-Q, --quit: Terminate remote instance.\n" "Note that these options default to the 0-th instance when no -N option is given,\n" "except for -L which defaults to the present instance (so as to be able to start\n" "playback immediately from the command line).\n" "\nOptions for file loading:\n" "-E, --enqueue: Don't clear the contents of the playlist when adding new items.\n" "-t[], --tab[=]: Add files to the specified playlist tab.\n" "\nIf you don't specify a session number via --session, the files will be opened by " "the new\ninstance, otherwise they will be sent to the already running instance you " "specify.\n" "\nOptions for changing state of Playlist/Music Store windows:\n" "-l [yes|no], --show-pl=[yes|no]: Show/hide playlist window.\n" "-m [yes|no], --show-ms=[yes|no]: Show/hide music store window.\n" "\nExamples:\n" "$ aqualung -s3 -o alsa -R -r 48000 -d plughw:0,0\n" "$ aqualung --srctype=1 --output oss --rate 96000\n" "$ aqualung -o jack -a -E `find ./ledzeppelin/ -name \"*.flac\"`\n"); fprintf(stderr, "\nDepending on the compile-time options, not all file formats\n" "and output drivers may be usable. Type aqualung -v to get a\n" "list of all the compiled-in features.\n\n"); } #ifdef HAVE_JACK void print_jack_failed_connection(void) { fprintf(stderr, "\nAqualung couldn't connect to JACK.\n"); fprintf(stderr, "There are several possible reasons:\n" "\t1) JACK is not running.\n" "\t2) JACK is running as another user, perhaps root.\n" "\t3) There is already another client called '%s'. (Use the -c option!)\n", client_name); fprintf(stderr, "Please consider the possibilities, and perhaps (re)start JACK.\n"); } void print_jack_SR_out_of_range(int SR) { fprintf(stderr, "\nThe JACK sample rate (%d Hz) is higher than MAX_SAMPLERATE.\n", SR); fprintf(stderr, "This is an arbitrary limit, which you may safely enlarge " "if you really need to.\n"); fprintf(stderr, "Currently MAX_SAMPLERATE = %d Hz.\n", MAX_SAMPLERATE); } #endif /* HAVE_JACK */ void setup_app_directories(void) { char * home = getenv("HOME"); if (!home) { char * homedir = (char *)g_get_home_dir(); strcpy(options.home, homedir); g_free(homedir); } else { strcpy(options.home, home); } snprintf(options.confdir, MAXLEN-1, "%s/.aqualung", options.home); strcpy(options.audiodir, options.home); strcpy(options.currdir, options.home); strcpy(options.exportdir, options.home); strcpy(options.plistdir, options.home); strcpy(options.podcastdir, options.home); strcpy(options.ripdir, options.home); strcpy(options.storedir, options.home); if (getcwd(options.cwd, MAXLEN) == NULL) { fprintf(stderr, "setup_app_directories(): warning: getcwd() returned NULL, using . as cwd\n"); strcpy(options.cwd, "."); } } int main(int argc, char ** argv) { int parse_run; int * argc_opt = NULL; char *** argv_opt = NULL; int argc_def = 0; char ** argv_def = NULL; thread_info_t thread_info; int c; int longopt_index = 0; extern int optind, opterr; int show_version = 0; int show_usage = 0; char * output_str = NULL; int rate = 0; int try_realtime = 0; int priority = -1; int disk_try_realtime = 0; int disk_priority = -1; char rcmd; int no_session = -1; int back = 0; int play = 0; int pause = 0; int stop = 0; int fwd = 0; int enqueue = 0; int remote_quit = 0; char * voladj_arg = NULL; char * optstring = "vho:d:c:r:a::RP:DY:s::l:m:N:BLUTFEV:Qt::"; struct option long_options[] = { { "version", 0, 0, 'v' }, { "help", 0, 0, 'h' }, { "output", 1, 0, 'o' }, { "device", 1, 0, 'd' }, { "client", 1, 0, 'c' }, { "rate", 1, 0, 'r' }, { "auto", 2, 0, 'a' }, { "realtime", 0, 0, 'R' }, { "priority", 1, 0, 'P' }, { "disk-realtime", 0, 0, 'D' }, { "disk-priority", 1, 0, 'Y' }, { "srctype", 2, 0, 's' }, { "show-pl", 1, 0, 'l' }, { "show-ms", 1, 0, 'm' }, { "tab", 2, 0, 't' }, { "session", 1, 0, 'N' }, { "back", 0, 0, 'B' }, { "play", 0, 0, 'L' }, { "pause", 0, 0, 'U' }, { "stop", 0, 0, 'T' }, { "fwd", 0, 0, 'F' }, { "enqueue", 0, 0, 'E' }, { "volume", 1, 0, 'V' }, { "quit", 0, 0, 'Q' }, { 0, 0, 0, 0 } }; #if defined(HAVE_JACK) || defined(HAVE_ALSA) || defined(HAVE_OSS) || defined(HAVE_SNDIO) || defined(HAVE_PULSE) int auto_driver_found = 0; #endif /* jack || alsa || oss || sndio || pulseaudio */ if (setenv("LC_NUMERIC", "POSIX", 1) != 0) { fprintf(stderr, "aqualung main(): setenv(\"LC_NUMERIC\", \"POSIX\") failed\n"); } #ifdef HAVE_JACK /* unlock memory (implicitly locked by libjack when Jack runs realtime) */ if (munlockall() < 0) { fprintf(stderr, "aqualung main(): munlockall() failed\n"); } #endif /* HAVE_JACK */ g_thread_init(NULL); gdk_threads_init(); #ifdef _WIN32 disk_thread_lock = g_mutex_new(); disk_thread_wake = g_cond_new(); #endif /* _WIN32 */ file_decoder_init(); setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, AQUALUNG_LOCALEDIR); textdomain(PACKAGE); bind_textdomain_codeset(PACKAGE, "UTF-8"); setup_app_directories(); load_default_cl(&argc_def, &argv_def); playlist_state = browser_state = -1; for (parse_run = 0; parse_run < 2; parse_run++) { if ((!parse_run) && (argc_def == 1)) ++parse_run; switch (parse_run) { case 0: argc_opt = &argc_def; argv_opt = &argv_def; break; case 1: argc_opt = &argc; argv_opt = &argv; break; } optind = opterr = 0; longopt_index = opterr = 0; while ((c = getopt_long(*argc_opt, *argv_opt, optstring, long_options, &longopt_index)) != -1) { switch (c) { case 1: /* getopt signals end of '-' options */ break; case 'h': show_usage++; break; case 'v': show_version++; break; case 'o': output_str = strdup(optarg); if (strcmp(output_str, "sndio") == 0) { #ifdef HAVE_SNDIO output = SNDIO_DRIVER; #else fprintf(stderr, "You selected sndio output, but this instance of Aqualung " "is compiled\n" "without sndio output support. Type aqualung -v to get a " "list of\n" "compiled-in features.\n"); exit(1); #endif /* HAVE_SNDIO*/ free(output_str); break; } if (strcmp(output_str, "oss") == 0) { #ifdef HAVE_OSS output = OSS_DRIVER; #else fprintf(stderr, "You selected OSS output, but this instance of Aqualung " "is compiled\n" "without OSS output support. Type aqualung -v to get a " "list of\n" "compiled-in features.\n"); exit(1); #endif /* HAVE_OSS*/ free(output_str); break; } if (strcmp(output_str, "pulse") == 0) { #ifdef HAVE_PULSE output = PULSE_DRIVER; #else fprintf(stderr, "You selected PulseAudio output, but this instance of Aqualung " "is compiled\n" "without PulseAudio output support. Type aqualung -v to get a " "list of\n" "compiled-in features.\n"); exit(1); #endif /* HAVE_PULSE*/ free(output_str); break; } if (strcmp(output_str, "alsa") == 0) { #ifdef HAVE_ALSA output = ALSA_DRIVER; #else fprintf(stderr, "You selected ALSA output, but this instance of Aqualung " "is compiled\n" "without ALSA output support. Type aqualung -v to get a " "list of\n" "compiled-in features.\n"); exit(1); #endif /* HAVE_ALSA */ free(output_str); break; } if (strcmp(output_str, "jack") == 0) { #ifdef HAVE_JACK output = JACK_DRIVER; #else fprintf(stderr, "You selected JACK output, but this instance of Aqualung " "is compiled\n" "without JACK output support. Type aqualung -v to get a " "list of\n" "compiled-in features.\n"); exit(1); #endif /* HAVE_JACK */ free(output_str); break; } if (strcmp(output_str, "win32") == 0) { #ifdef _WIN32 output = WIN32_DRIVER; #else fprintf(stderr, "You selected WIN32 output, but this instance of Aqualung " "is compiled\n" "without WIN32 output support. Type aqualung -v to get a " "list of\n" "compiled-in features.\n"); exit(1); #endif /* _WIN32 */ free(output_str); break; } fprintf(stderr, "Invalid output device: %s\n", output_str); free(output_str); exit(0); break; case 'd': device_name = strdup(optarg); break; case 'c': #ifdef HAVE_JACK client_name = strdup(optarg); #endif /* HAVE_JACK */ break; case 'r': rate = atoi(optarg); break; case 'a': #ifdef HAVE_JACK auto_connect = 1; if (optarg) { char * s; if (strstr(optarg, ",") == NULL) { fprintf(stderr, "Invalid ports specification: %s\n", optarg); exit(0); } s = strtok(optarg, ","); if (s != NULL) { user_port1 = strdup(s); } else { fprintf(stderr, "Invalid ports specification: argument " "contains too few ports\n"); exit(0); } s = strtok(NULL, ","); if (s != NULL) { user_port2 = strdup(s); } else { fprintf(stderr, "Invalid ports specification: argument " "contains too few ports\n"); exit(0); } default_ports = 0; } #endif /* HAVE_JACK */ break; case 'R': try_realtime = 1; break; case 'P': priority = atoi(optarg); break; case 'D': disk_try_realtime = 1; break; case 'Y': disk_priority = atoi(optarg); break; case 's': #ifdef HAVE_SRC if (optarg) { options.src_type = atoi(optarg); ++src_type_parsed; } else { int i = 0; fprintf(stderr, "List of available Sample Rate Converters:\n\n"); while (src_get_name(i)) { fprintf(stderr, "Converter #%d: %s\n%s\n\n", i, src_get_name(i), src_get_description(i)); ++i; } fprintf(stderr, "Type aqualung --srctype=n ... or aqualung -sn ... to choose " "Converter #n.\n\n"); exit(0); } #else if (optarg) { fprintf(stderr, "You attempted to set the type of the internal Sample Rate " "Converter," "\nbut this instance of Aqualung is compiled without " "support for" "\ninternal Sample Rate Conversion. Type aqualung -v to get " "a list" "\nof compiled-in features.\n"); } else { fprintf(stderr, "You attempted to list the available types for the internal " "Sample" "\nRate Converter, but this instance of Aqualung is " "compiled without" "\nsupport for internal Sample Rate Conversion. Type " "aqualung -v to" "\nget a list of compiled-in features.\n"); } exit(1); #endif /* HAVE_SRC */ break; case 'l': if(!strncmp(optarg, "yes", 3)) { playlist_state = 1; } else if(!strncmp(optarg, "no", 2)) { playlist_state = 0; } break; case 'm': if(!strncmp(optarg, "yes", 3)) { browser_state = 1; } else if(!strncmp(optarg, "no", 2)) { browser_state = 0; } break; case 't': if (optarg != NULL) { tab_name = strdup(optarg); } else { tab_name = strdup(""); } break; case 'N': no_session = atoi(optarg); break; case 'B': back++; break; case 'L': play++; break; case 'U': pause++; break; case 'T': stop++; break; case 'F': fwd++; break; case 'E': enqueue++; break; case 'V': voladj_arg = strdup(optarg); break; case 'Q': remote_quit++; break; default: show_usage++; break; } } } free(argv_def); if (show_version) { print_version(); exit(1); } if (show_usage) { print_usage(); exit(1); } if (back) { if (no_session == -1) no_session = 0; rcmd = RCMD_BACK; send_message_to_session(no_session, &rcmd, 1); exit(0); } if (pause) { if (no_session == -1) no_session = 0; rcmd = RCMD_PAUSE; send_message_to_session(no_session, &rcmd, 1); exit(0); } if (stop) { if (no_session == -1) no_session = 0; rcmd = RCMD_STOP; send_message_to_session(no_session, &rcmd, 1); exit(0); } if (fwd) { if (no_session == -1) no_session = 0; rcmd = RCMD_FWD; send_message_to_session(no_session, &rcmd, 1); exit(0); } if (remote_quit) { if (no_session == -1) no_session = 0; rcmd = RCMD_QUIT; send_message_to_session(no_session, &rcmd, 1); exit(1); } if (voladj_arg) { char buf[MAXLEN]; if (no_session == -1) no_session = 0; buf[0] = RCMD_VOLADJ; buf[1] = '\0'; strncat(buf, voladj_arg, MAXLEN-2); send_message_to_session(no_session, buf, strlen(buf)); exit(1); } if (no_session != -1) { char sockname[MAXLEN]; sprintf(sockname, "/tmp/aqualung_%s.%d", g_get_user_name(), no_session); if (!g_file_test(sockname, G_FILE_TEST_EXISTS)) { no_session = -1; } } { int i; char buffer[MAXLEN]; char fullname[MAXLEN]; if (no_session != -1) { for (i = optind; argv[i] != NULL; i++) { normalize_filename(argv[i], fullname); buffer[0] = RCMD_ADD_FILE; buffer[1] = '\0'; strncat(buffer, fullname, MAXLEN-2); send_message_to_session(no_session, buffer, strlen(buffer)); } if (argv[optind] != NULL) { buffer[0] = RCMD_ADD_COMMIT; buffer[1] = (enqueue) ? 1 : 0; buffer[2] = (play) ? 1 : 0; buffer[3] = (tab_name != NULL) ? 1 : 0; buffer[4] = '\0'; if (tab_name != NULL) { strncat(buffer + 4, tab_name, MAXLEN-5); } send_message_to_session(no_session, buffer, 4 + strlen(buffer + 4)); exit(0); } } } if (play) { if (no_session == -1) { immediate_start = 1; } else { rcmd = RCMD_PLAY; send_message_to_session(no_session, &rcmd, 1); exit(0); } } #ifdef _WIN32 if (output == 0) { output = WIN32_DRIVER; } #endif /* _WIN32 */ /* Initialize thread_info and create ringbuffers */ memset(&thread_info, 0, sizeof(thread_info)); thread_info.rb_size = RB_AUDIO_SIZE; rb = rb_create(2*sample_size * thread_info.rb_size); memset(rb->buf, 0, rb->size); rb_disk2gui = rb_create(RB_CONTROL_SIZE); memset(rb_disk2gui->buf, 0, rb_disk2gui->size); rb_gui2disk = rb_create(RB_CONTROL_SIZE); memset(rb_gui2disk->buf, 0, rb_gui2disk->size); rb_disk2out = rb_create(RB_CONTROL_SIZE); memset(rb_disk2out->buf, 0, rb_disk2out->size); rb_out2disk = rb_create(RB_CONTROL_SIZE); memset(rb_out2disk->buf, 0, rb_out2disk->size); thread_info.is_streaming = 0; thread_info.is_mono = 0; thread_info.in_SR = 0; #ifdef HAVE_JACK if ((output != JACK_DRIVER) && (rate == 0)) { rate = 44100; } #else if (rate == 0) { rate = 44100; } #endif /* HAVE_JACK */ /* try to find a suitable output driver */ if (output == 0) { printf("No output driver specified, probing for a usable driver.\n"); } #ifdef HAVE_JACK if (output == 0) { int ret; /* probe Jack */ printf("Probing JACK driver... "); ret = jack_init(&thread_info); if (ret == -1) { printf("JACK server not found\n"); } else if (ret < 0) { printf("Output samplerate (%d Hz) out of range\n", -ret); } else { output = JACK_DRIVER; rate = thread_info.out_SR; auto_connect = 1; auto_driver_found = 1; printf("OK\n"); } } #endif /* HAVE_JACK */ #ifdef HAVE_PULSE if (output == 0) { int ret; /* probe PulseAudio */ printf("Probing PulseAudio driver... "); thread_info.out_SR = rate; ret = pulse_init(&thread_info, 0, try_realtime, priority); if (ret == -1) { printf("sample rate out of range!\n"); } else if (ret > 0) { printf("unable to initialize PulseAudio: %s\n", pa_strerror(ret)); } else { output = PULSE_DRIVER; auto_driver_found = 1; printf("OK\n"); } } #endif /* HAVE_PULSE */ #ifdef HAVE_ALSA if (output == 0) { /* probe ALSA */ int ret; printf("Probing ALSA driver... "); if (device_name == NULL) { device_name = strdup("default"); } thread_info.out_SR = rate; thread_info.pcm_name = strdup(device_name); ret = alsa_init(&thread_info, 0); if (ret == -1) { printf("device busy\n"); } else if (ret < 0) { printf("unable to start with default params\n"); } else { output = ALSA_DRIVER; auto_driver_found = 1; printf("OK\n"); } } #endif /* HAVE_ALSA */ #ifdef HAVE_SNDIO if (output == 0) { /* probe sndio */ int ret; printf("Probing sndio driver... "); thread_info.out_SR = rate; ret = sndio_init(&thread_info, 0, try_realtime, priority); if (ret < 0) { printf("unable to start with default params\n"); } else { output = SNDIO_DRIVER; auto_driver_found = 1; printf("OK\n"); } } #endif /* HAVE_SNDIO */ #ifdef HAVE_OSS if (output == 0) { /* probe OSS */ int ret; printf("Probing OSS driver... "); if (device_name == NULL) { device_name = strdup(OSS_DEVICE); } thread_info.out_SR = rate; ret = oss_init(&thread_info, 0, try_realtime, priority); if (ret == -1) { printf("device busy\n"); } else if (ret < 0) { printf("unable to start with default params\n"); } else { output = OSS_DRIVER; auto_driver_found = 1; printf("OK\n"); } } #endif /* HAVE_OSS */ /* if no output driver was found, give up and exit */ if (output == 0) { fprintf(stderr, "No usable output driver was found. Please see aqualung --help\n" "and the docs for more info on successfully starting the program.\n"); exit(1); } #ifdef HAVE_JACK if ((output == JACK_DRIVER) && (!auto_driver_found) && (rate > 0)) { fprintf(stderr, "You attempted to set the output rate for the JACK output.\n" "We won't do this; please use the --rate option with the\n" "oss and alsa outputs only.\n" "In case of the JACK output, the (already running) JACK server\n" "will determine the output sample rate to use.\n"); exit(1); } #endif /* HAVE_JACK */ if (device_name == NULL) { #ifdef HAVE_OSS if (output == OSS_DRIVER) { device_name = strdup(OSS_DEVICE); } #endif /* HAVE_OSS */ #ifdef HAVE_ALSA if (output == ALSA_DRIVER) { device_name = strdup("default"); } #endif /* HAVE_ALSA */ } #ifdef HAVE_JACK if (output == JACK_DRIVER) { if (!auto_driver_found) { int ret = jack_init(&thread_info); if (ret == -1) { print_jack_failed_connection(); exit(1); } else if (ret < 0) { print_jack_SR_out_of_range(-ret); exit(1); } else { rate = thread_info.out_SR; } } } #endif /* HAVE_JACK */ #ifdef HAVE_ALSA if (output == ALSA_DRIVER) { if (!auto_driver_found) { int ret; thread_info.out_SR = rate; thread_info.pcm_name = strdup(device_name); ret = alsa_init(&thread_info, 1); if (ret < 0) { exit(1); } } } #endif /* HAVE_ALSA */ #ifdef HAVE_SNDIO if (output == SNDIO_DRIVER) { thread_info.out_SR = rate; } #endif /* HAVE_SNDIO */ #ifdef HAVE_OSS if (output == OSS_DRIVER) { thread_info.out_SR = rate; } #endif /* HAVE_OSS */ #ifdef HAVE_PULSE if (output == PULSE_DRIVER) { thread_info.out_SR = rate; } #endif /* HAVE_PULSE */ #ifdef _WIN32 if (output == WIN32_DRIVER) { thread_info.out_SR = rate; } #endif /* _WIN32 */ /* startup disk thread */ AQUALUNG_THREAD_CREATE(thread_info.disk_thread_id, NULL, disk_thread, &thread_info) #ifdef _WIN32 g_thread_set_priority(thread_info.disk_thread_id, G_THREAD_PRIORITY_URGENT); #else set_thread_priority(thread_info.disk_thread_id, "disk", disk_try_realtime, disk_priority); #endif /* _WIN32 */ #ifdef HAVE_SNDIO if (output == SNDIO_DRIVER) { if (!auto_driver_found) { int ret = sndio_init(&thread_info, 1, try_realtime, priority); if (ret < 0) { exit(1); } } } #endif /* HAVE_SNDIO */ #ifdef HAVE_OSS if (output == OSS_DRIVER) { if (!auto_driver_found) { int ret = oss_init(&thread_info, 1, try_realtime, priority); if (ret < 0) { exit(1); } } } #endif /* HAVE_OSS */ #ifdef HAVE_PULSE if (output == PULSE_DRIVER) { if (!auto_driver_found) { int ret = pulse_init(&thread_info, 1, try_realtime, priority); if (ret != 0) { exit(1); } } } #endif /* HAVE_PULSE */ #ifdef HAVE_ALSA if (output == ALSA_DRIVER) { AQUALUNG_THREAD_CREATE(thread_info.alsa_thread_id, NULL, alsa_thread, &thread_info) set_thread_priority(thread_info.alsa_thread_id, "ALSA output", try_realtime, priority); } #endif /* HAVE_ALSA */ #ifdef _WIN32 if (output == WIN32_DRIVER) { AQUALUNG_THREAD_CREATE(thread_info.win32_thread_id, NULL, win32_thread, &thread_info) g_thread_set_priority(thread_info.win32_thread_id, G_THREAD_PRIORITY_URGENT); } #endif /* _WIN32 */ create_gui(argc, argv, optind, enqueue, rate, RB_AUDIO_SIZE * rate / 44100.0); setup_app_socket(); run_gui(); /* control stays here until user exits program */ close_app_socket(); AQUALUNG_THREAD_JOIN(thread_info.disk_thread_id) #ifdef HAVE_SNDIO if (output == SNDIO_DRIVER) { AQUALUNG_THREAD_JOIN(thread_info.sndio_thread_id) free(thread_info.sndio_short_buf); sio_close(thread_info.sndio_hdl); } #endif /* HAVE_SNDIO */ #ifdef HAVE_OSS if (output == OSS_DRIVER) { AQUALUNG_THREAD_JOIN(thread_info.oss_thread_id) free(thread_info.oss_short_buf); ioctl(thread_info.fd_oss, SNDCTL_DSP_RESET, 0); close(thread_info.fd_oss); } #endif /* HAVE_OSS */ #ifdef HAVE_PULSE if (output == PULSE_DRIVER) { AQUALUNG_THREAD_JOIN(thread_info.pulse_thread_id) free(thread_info.pa_short_buf); pa_simple_free(thread_info.pa); } #endif /* HAVE_PULSE */ #ifdef HAVE_ALSA if (output == ALSA_DRIVER) { AQUALUNG_THREAD_JOIN(thread_info.alsa_thread_id) free(thread_info.pcm_name); snd_pcm_close(thread_info.pcm_handle); if (thread_info.is_output_32bit) free(thread_info.alsa_int_buf); else free(thread_info.alsa_short_buf); } #endif /* HAVE_ALSA */ #ifdef HAVE_JACK if (output == JACK_DRIVER) { jack_client_close(jack_client); free(client_name); } #endif /* HAVE_JACK */ #ifdef _WIN32 if (output == WIN32_DRIVER) { AQUALUNG_THREAD_JOIN(thread_info.win32_thread_id) } g_mutex_free(disk_thread_lock); g_cond_free(disk_thread_wake); #endif /* _WIN32 */ if (device_name != NULL) free(device_name); free(l_buf); free(r_buf); rb_free(rb); rb_free(rb_disk2gui); rb_free(rb_gui2disk); rb_free(rb_disk2out); rb_free(rb_out2disk); return 0; } // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/cover.h0000644000175000001440000000360110727033063013171 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi (C) 2006 Tomasz Maka This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: cover.h 906 2007-12-06 17:18:06Z tszilagyi $ */ #ifndef _COVER_H #define _COVER_H /* FIXME 34 is space for scrollbar width, window border and it is theme dependent */ #define SCROLLBAR_WIDTH 34 #define N_COVER_WIDTHS 5 void display_cover (GtkWidget *image_area, GtkWidget *event_area, GtkWidget *cover_align, gint dest_width, gint dest_height, gchar *song_filename, gboolean hide, gboolean bevel); void display_cover_from_binary(GtkWidget *image_area, GtkWidget *event_area, GtkWidget *align, gint dest_width, gint dest_height, void * data, int length, gboolean hide, gboolean bevel); void display_zoomed_cover (GtkWidget *window, GtkWidget *event_area, gchar *song_filename); void display_zoomed_cover_from_binary(GtkWidget *window, GtkWidget *event_area, void * data, int length); void insert_cover (GtkTreeIter * tree_iter, GtkTextIter * text_iter, GtkTextBuffer * buffer); #endif /* _COVER_H */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/cover.c0000644000175000001440000004054510752404220013167 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi (C) 2006 Tomasz Maka This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: cover.c 990 2008-01-29 18:10:33Z peterszilagyi $ */ #include #include #include #include #include #include #include #include #include "common.h" #include "cover.h" #include "gui_main.h" #include "music_browser.h" #include "store_file.h" #include "i18n.h" #include "options.h" extern options_t options; extern gint cover_show_flag; extern GtkWidget * main_window; extern GtkTreeStore * music_store; /* maximum 4 chars per extension */ gchar *cover_extensions[] = { "jpg", "jpeg", "png", "gif", "bmp", "tif", "tiff" }; gint n_extensions = sizeof(cover_extensions) / sizeof(gchar*); GtkWidget *cover_window; gboolean ext_flag; gchar temp_filename[PATH_MAX]; gint calculated_width, calculated_height; gint cover_widths[N_COVER_WIDTHS] = { 50, 100, 200, 300, -1 }; /* widths in pixels */ gchar * get_song_path(gchar *song_filename) { static gchar song_path[PATH_MAX]; gint i = 0; gchar *pos; if ((pos = strrchr(song_filename, '/'))) { for (i=0; song_filename <= pos; i++) { song_path[i] = *song_filename++; } } song_path[i] = '\0'; return song_path; } static gint entry_filter(const struct dirent *entry) { gint i, len; gchar *ext, *str1, *str2; len = strlen (entry->d_name); if (len < 5) /* 5 => a.abc */ return FALSE; if ((ext = strrchr(entry->d_name, '.'))) { ext++; /* filter candidates for cover */ str1 = g_utf8_casefold(ext, -1); for (i = 0; i < n_extensions; i++) { str2 = g_utf8_casefold(cover_extensions[i], -1); if (!g_utf8_collate(str1, str2)) { g_free(str1); g_free(str2); ext_flag = TRUE; strncpy(temp_filename, entry->d_name, PATH_MAX-1); return TRUE; } g_free (str2); } g_free (str1); } return FALSE; } gchar * find_cover_filename(gchar *song_filename) { gchar *cover_filenames[] = { "cover", ".cover", "folder", ".folder", "front", ".front" }; gint n_templates, n_file_hits, i, j, n, m; gchar base_path[PATH_MAX], current_filename[PATH_MAX]; static gchar cover_filename[PATH_MAX]; static gint cover_filename_reasonable; struct dirent ** d_entry; gchar *str1, *str2; n_templates = sizeof(cover_filenames) / sizeof(gchar*); strcpy(base_path, get_song_path(song_filename)); if (strcmp(base_path, get_song_path(cover_filename))) { cover_filename[0] = temp_filename[0] = '\0'; cover_filename_reasonable = FALSE; ext_flag = FALSE; n_file_hits = scandir(base_path, &d_entry, entry_filter, alphasort); for (i = 0; i < n_templates; i++) { for (j = 0; j < n_extensions; j++) { strcpy (current_filename, cover_filenames[i]); strcat (current_filename, "."); strcat (current_filename, cover_extensions[j]); str1 = g_utf8_casefold (current_filename, -1); for (n = 0; n < n_file_hits; n++) { str2 = g_utf8_casefold(d_entry[n]->d_name, -1); if (!g_utf8_collate(str1, str2)) { strcpy (cover_filename, base_path); strcat (cover_filename, d_entry[n]->d_name); if (g_file_test (cover_filename, G_FILE_TEST_IS_REGULAR) == TRUE) { g_free (str1); g_free (str2); for (m = 0; m < n_file_hits; m++) { free(d_entry[m]); } free(d_entry); cover_filename_reasonable = TRUE; return cover_filename; } } g_free (str2); } g_free (str1); } } if (n_file_hits > 0) { for (m = 0; m < n_file_hits; m++) { free(d_entry[m]); } free(d_entry); } strcpy (cover_filename, base_path); if (ext_flag == TRUE) { strcat (cover_filename, temp_filename); cover_filename_reasonable = TRUE; } } if (cover_filename_reasonable == TRUE) { return cover_filename; } return NULL; } void draw_cover_frame(GdkPixbuf *pixbuf, gint width, gint height, gboolean bevel) { gint rowstride, channels; gint i, bc1, bc2, bc3, bc4; guchar *pixels, *p; gchar *c = NULL; bc1 = bc2 = bc3 = bc4 = 64; /* dark edges */ if (bevel == TRUE) { bc2 = bc4 = 160; /* light edges */ } /* set high contrast bevel if "plain" or "no_skin" is the current skin */ if ((c = strrchr(options.skin, '/')) != NULL) { ++c; if (strcasecmp(c, "plain") == 0 || strcasecmp(c, "no_skin") == 0) { bc1 = bc2 = bc3 = bc4 = 0; /* dark edges */ if (bevel == TRUE) { bc2 = bc4 = 255; /* light edges */ } } } /* draw frame */ channels = gdk_pixbuf_get_n_channels (pixbuf); rowstride = gdk_pixbuf_get_rowstride (pixbuf); pixels = gdk_pixbuf_get_pixels (pixbuf); /* horizontal lines */ for(i=0; i < width; i++) { p = pixels + i * channels; p[0] = p[1] = p[2] = bc1; p = pixels + (height-1) * rowstride + i * channels; p[0] = p[1] = p[2] = bc2; } /* vertical lines */ for(i=0; i < height; i++) { p = pixels + i * rowstride; p[0] = p[1] = p[2] = bc3; p = pixels + i * rowstride + (width-1) * channels; p[0] = p[1] = p[2] = bc4; } } gboolean cover_window_close_cb(GtkWidget * widget, GdkEvent * event, gpointer data) { gtk_widget_destroy(widget); return TRUE; } gint cover_window_key_pressed(GtkWidget * widget, GdkEventKey * kevent) { if (kevent->keyval == GDK_Escape) { cover_window_close_cb(widget, NULL, NULL); return TRUE; } return FALSE; } void create_zoomed_cover_window(gint * size, GtkWidget * window, GtkWidget ** image_area) { *size = cover_widths[options.cover_width]; if (*size == -1) { *size = cover_widths[options.cover_width-1]; } cover_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); g_signal_connect(G_OBJECT(cover_window), "button_press_event", G_CALLBACK(cover_window_close_cb), NULL); g_signal_connect(G_OBJECT(cover_window), "key_press_event", G_CALLBACK(cover_window_key_pressed), NULL); gtk_window_set_position(GTK_WINDOW(cover_window), GTK_WIN_POS_MOUSE); gtk_widget_set_events(cover_window, GDK_BUTTON_PRESS_MASK); gtk_window_set_modal(GTK_WINDOW(cover_window), TRUE); gtk_window_set_transient_for(GTK_WINDOW(cover_window), GTK_WINDOW(window)); gtk_window_set_decorated(GTK_WINDOW(cover_window), FALSE); *image_area = gtk_image_new(); gtk_widget_show(*image_area); gtk_container_add (GTK_CONTAINER (cover_window), *image_area); } void display_zoomed_cover(GtkWidget *window, GtkWidget *event_area, gchar *song_filename) { GtkWidget * image_area; gint size; if (g_file_test(song_filename, G_FILE_TEST_IS_REGULAR) != TRUE) { return; } create_zoomed_cover_window(&size, window, &image_area); display_cover(image_area, event_area, NULL, size, size, song_filename, FALSE, FALSE); gtk_widget_set_size_request(cover_window, calculated_width, calculated_height); gtk_widget_show(cover_window); } void display_zoomed_cover_from_binary(GtkWidget *window, GtkWidget *event_area, void * data, int length) { GtkWidget * image_area; gint size; if (data == NULL) { return; } create_zoomed_cover_window(&size, window, &image_area); display_cover_from_binary(image_area, event_area, NULL, size, size, data, length, FALSE, FALSE); gtk_widget_set_size_request(cover_window, calculated_width, calculated_height); gtk_widget_show(cover_window); } void display_cover_from_pixbuf(GtkWidget *image_area, GtkWidget *event_area, GtkWidget *align, gint dest_width, gint dest_height, GdkPixbuf * cover_pixbuf, gboolean hide, gboolean bevel) { GdkPixbuf * cover_pixbuf_scaled; gint width = gdk_pixbuf_get_width(cover_pixbuf); gint height = gdk_pixbuf_get_height(cover_pixbuf); gint scaled_width, scaled_height; if (cover_pixbuf == NULL) { return; } calculated_width = dest_width; calculated_height = dest_height; /* don't scale when orginal size is smaller than cover defaults */ scaled_width = dest_width; scaled_height = dest_height; if (width >= height) { scaled_height = (height * dest_height) / width; } else { scaled_width = (width * dest_width) / height; } cover_pixbuf_scaled = gdk_pixbuf_scale_simple(cover_pixbuf, scaled_width, scaled_height, GDK_INTERP_TILES); if (cover_pixbuf_scaled == NULL) { return; } draw_cover_frame(cover_pixbuf_scaled, scaled_width, scaled_height, bevel); calculated_width = scaled_width; calculated_height = scaled_height; gtk_image_set_from_pixbuf(GTK_IMAGE(image_area), cover_pixbuf_scaled); g_object_unref(cover_pixbuf_scaled); if (!cover_show_flag && hide == TRUE) { cover_show_flag = 1; gtk_widget_show(image_area); gtk_widget_show(event_area); if (align) { gtk_widget_show(align); } } /* don't unref cover_pixbuf that was passed in */ } void hide_cover(GtkWidget *image_area, GtkWidget *event_area, GtkWidget *align) { cover_show_flag = 0; gtk_widget_hide(image_area); gtk_widget_hide(event_area); if (align) { gtk_widget_hide(align); } } void display_cover(GtkWidget *image_area, GtkWidget *event_area, GtkWidget *align, gint dest_width, gint dest_height, gchar *song_filename, gboolean hide, gboolean bevel) { GdkPixbuf * cover_pixbuf = NULL; gchar cover_filename[PATH_MAX]; char * filename = NULL; if (strlen(song_filename) == 0) { if (hide == TRUE) { hide_cover(image_area, event_area, align); } return; } if ((filename = find_cover_filename(song_filename)) == NULL) { if (hide == TRUE) { hide_cover(image_area, event_area, align); } return; } strcpy(cover_filename, filename); if ((cover_pixbuf = gdk_pixbuf_new_from_file(cover_filename, NULL)) != NULL) { display_cover_from_pixbuf(image_area, event_area, align, dest_width, dest_height, cover_pixbuf, hide, bevel); g_object_unref(cover_pixbuf); } else if (hide == TRUE) { hide_cover(image_area, event_area, align); } } void display_cover_from_binary(GtkWidget *image_area, GtkWidget *event_area, GtkWidget *align, gint dest_width, gint dest_height, void * data, int length, gboolean hide, gboolean bevel) { GdkPixbuf * cover_pixbuf = NULL; GdkPixbufLoader * loader; if (data == NULL) { return; } loader = gdk_pixbuf_loader_new(); if (gdk_pixbuf_loader_write(loader, data, length, NULL) != TRUE) { fprintf(stderr, "display_cover_from_binary: failed to load image #1\n"); g_object_unref(loader); return; } if (gdk_pixbuf_loader_close(loader, NULL) != TRUE) { fprintf(stderr, "display_cover_from_binary: failed to load image #2\n"); g_object_unref(loader); return; } if ((cover_pixbuf = gdk_pixbuf_loader_get_pixbuf(loader)) != NULL) { display_cover_from_pixbuf(image_area, event_area, align, dest_width, dest_height, cover_pixbuf, hide, bevel); /* cover_pixbuf is owned by loader, so don't unref that manually */ g_object_unref(loader); } else if (hide == TRUE) { hide_cover(image_area, event_area, align); } } void insert_cover(GtkTreeIter * tree_iter, GtkTextIter * text_iter, GtkTextBuffer * buffer) { GtkTreePath * path; gchar cover_filename[PATH_MAX]; gint depth; track_data_t * data; GdkPixbuf * pixbuf; gint k; gint d_cover_width, d_cover_height; char * filename = NULL; gint width, height; gint scaled_width, scaled_height; GdkPixbuf * scaled; /* get cover path */ path = gtk_tree_model_get_path(GTK_TREE_MODEL(music_store), tree_iter); depth = gtk_tree_path_get_depth(path); gtk_tree_path_free(path); /* check if we at 3rd level (album) or 4th level (track) */ if (depth < 3) { return; } if (depth == 3) { /* album selected */ GtkTreeIter iter; if (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &iter, tree_iter, 0)) { gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter, MS_COL_DATA, &data, -1); } else { return; } } else { /* track selected */ gtk_tree_model_get(GTK_TREE_MODEL(music_store), tree_iter, MS_COL_DATA, &data, -1); } if ((filename = find_cover_filename(data->file)) == NULL) { return; } strcpy(cover_filename, filename); /* load and display cover */ k = cover_widths[options.cover_width % N_COVER_WIDTHS]; if (k == -1) { d_cover_width = d_cover_height = options.browser_size_x - SCROLLBAR_WIDTH; } else { d_cover_width = d_cover_height = k; } if ((pixbuf = gdk_pixbuf_new_from_file (cover_filename, NULL)) == NULL) { return; } gdk_pixbuf_get_file_info(cover_filename, &width, &height); /* don't scale when orginal size is smaller than cover defaults */ scaled_width = d_cover_width; scaled_height = d_cover_height; if (width > d_cover_width || height > d_cover_height) { if (width >= height) { scaled_height = (height * d_cover_width) / width; } else { scaled_width = (width * d_cover_height) / height; } scaled = gdk_pixbuf_scale_simple (pixbuf, scaled_width, scaled_height, GDK_INTERP_TILES); g_object_unref (pixbuf); pixbuf = scaled; } else { if (options.magnify_smaller_images) { scaled_height = (height * d_cover_width) / width; scaled = gdk_pixbuf_scale_simple (pixbuf, scaled_width, scaled_height, GDK_INTERP_TILES); g_object_unref (pixbuf); pixbuf = scaled; } else { scaled_width = width; scaled_height = height; } } draw_cover_frame(pixbuf, scaled_width, scaled_height, FALSE); /* insert picture */ gtk_text_buffer_insert_pixbuf (buffer, text_iter, pixbuf); gtk_text_buffer_insert (buffer, text_iter, "\n\n", -1); g_object_unref (pixbuf); } // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/export.h0000644000175000001440000000451311006604372013375 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: export.h 1023 2008-05-02 12:28:41Z tszilagyi $ */ #ifndef _EXPORT_H #define _EXPORT_H #include #if defined(HAVE_SNDFILE) || defined(HAVE_FLAC) || defined(HAVE_VORBISENC) || defined(HAVE_LAME) #define HAVE_EXPORT #include "common.h" typedef struct _export_map_t { char * key; char * val; struct _export_map_t * next; } export_map_t; typedef struct { AQUALUNG_THREAD_DECLARE(thread_id); AQUALUNG_MUTEX_DECLARE(mutex); GSList * slist; char outdir[MAXLEN]; char template[MAXLEN]; int dir_for_artist; int dir_for_album; int dir_len_limit; export_map_t * artist_map; export_map_t * record_map; int format; int bitrate; int vbr; int write_meta; int filter_same; int excl_enabled; char ** excl_patternv; int cancelled; int progbar_tag; char file1[MAXLEN]; char file2[MAXLEN]; double ratio; GtkWidget * dialog; GtkWidget * format_combo; GtkWidget * check_dir_artist; GtkWidget * check_dir_album; GtkWidget * dirlen_spin; GtkWidget * bitrate_scale; GtkWidget * bitrate_label; GtkWidget * bitrate_value_label; GtkWidget * vbr_check; GtkWidget * meta_check; GtkWidget * slot; GtkWidget * prog_file_entry1; GtkWidget * prog_file_entry2; GtkWidget * prog_cancel_button; GtkWidget * progbar; } export_t; export_t * export_new(void); void export_append_item(export_t * export, char * infile, char * artist, char * album, char * title, int year, int no); int export_start(export_t * export); #endif /* HAVE_SNDFILE || ... */ #endif /* _EXPORT_H */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/export.c0000644000175000001440000010261011100115547013361 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: export.c 1030 2008-10-13 17:42:07Z peterszilagyi $ */ #include #include #include #include #include #include #include #include #include #include #include #ifdef _WIN32 #include #else #include #endif /* _WIN32 */ #include "common.h" #include "i18n.h" #include "utils.h" #include "utils_gui.h" #include "decoder/file_decoder.h" #include "encoder/file_encoder.h" #include "encoder/enc_lame.h" #include "store_file.h" #include "playlist.h" #include "export.h" #include "options.h" #ifdef HAVE_EXPORT #define BUFSIZE 10240 extern GtkWidget * browser_window; extern options_t options; GtkWidget * export_window; int export_slot_count; typedef struct { char * infile; char * artist; char * album; char * title; int year; int no; } export_item_t; char * export_compress_str(char * buf, int limit) { char * str; char * valid = "abcdefghijklmnopqrstuvwxyz0123456789"; int i = 0; int j = 0; str = g_ascii_strdown(buf, -1); g_strcanon(str, valid, '_'); for (i = 0; str[i]; i++) { if (str[i] == '_') { continue; } str[j] = str[i]; j++; } if (limit < j) { str[limit] = '\0'; } else if (j > 0) { str[j] = '\0'; } else { str[0] = 'x'; str[1] = '\0'; } return str; } int export_map_has(export_map_t * map, char * val) { export_map_t * pmap; for (pmap = map; pmap; pmap = pmap->next) { if (!strcmp(pmap->val, val)) { return 1; } } return 0; } export_map_t * export_map_new(export_map_t * _map, char * key, int limit) { export_map_t * map; char * tmp; int i = '2'; if ((map = (export_map_t *)malloc(sizeof(export_map_t))) == NULL) { fprintf(stderr, "export_map_new(): malloc error\n"); return NULL; } map->next = NULL; map->key = g_utf8_casefold(key, -1); tmp = export_compress_str(key, limit); while (export_map_has(_map, tmp) && i <= 'z') { tmp[strlen(tmp)-1] = i; if ((i >= '2' && i < '9') || (i >= 'a' && i <= 'z')) { ++i; } else { i = 'a'; } } map->val = strdup(tmp); g_free(tmp); return map; } char * export_map_put(export_map_t ** map, char * key, int limit) { export_map_t * pmap; export_map_t * _pmap; if (key == NULL || key[0] == '\0') { return NULL; } if (*map == NULL) { *map = export_map_new(NULL, key, limit); return (*map)->val; } else { char * key1 = g_utf8_casefold(key, -1); for (_pmap = pmap = *map; pmap; _pmap = pmap, pmap = pmap->next) { if (!g_utf8_collate(key1, pmap->key)) { g_free(key1); return pmap->val; } } g_free(key1); _pmap->next = export_map_new(*map, key, limit); return _pmap->next->val; } } void export_map_free(export_map_t * map) { export_map_t * pmap; for (pmap = map; pmap; map = pmap) { pmap = map->next; g_free(map->key); free(map->val); free(map); } } export_t * export_new(void) { export_t * export; if ((export = (export_t *)calloc(1, sizeof(export_t))) == NULL) { fprintf(stderr, "export_new: calloc error\n"); return NULL; } #ifdef _WIN32 export->mutex = g_mutex_new(); #endif /* _WIN32 */ return export; } void export_item_free(export_item_t * item) { free(item->infile); free(item->artist); free(item->album); free(item->title); free(item); } void export_free(export_t * export) { GSList * node; #ifdef _WIN32 g_mutex_free(export->mutex); #endif /* _WIN32 */ for (node = export->slist; node; node = node->next) { export_item_free((export_item_t *)node->data); } g_slist_free(export->slist); g_strfreev(export->excl_patternv); export_map_free(export->artist_map); export_map_free(export->record_map); free(export); } void export_append_item(export_t * export, char * infile, char * artist, char * album, char * title, int year, int no) { export_item_t * item; if ((item = (export_item_t *)calloc(1, sizeof(export_item_t))) == NULL) { fprintf(stderr, "export_append_item: calloc error\n"); return; } item->infile = strdup(infile); item->artist = (artist && artist[0] != '\0') ? strdup(artist) : strdup(_("Unknown Artist")); item->album = (album && album[0] != '\0') ? strdup(album) : strdup(_("Unknown Album")); item->title = (title && title[0] != '\0') ? strdup(title) : strdup(_("Unknown Track")); item->year = year; item->no = no; export->slist = g_slist_append(export->slist, item); } gboolean export_finish(gpointer user_data) { export_t * export = (export_t *)user_data; gtk_window_resize(GTK_WINDOW(export_window), export_window->allocation.width, export_window->allocation.height - export->slot->allocation.height); gtk_widget_destroy(export->slot); export->slot = NULL; g_source_remove(export->progbar_tag); export_free(export); --export_slot_count; if (export_slot_count == 0) { unregister_toplevel_window(export_window); gtk_widget_destroy(export_window); export_window = NULL; } return FALSE; } int export_item_set_path(export_t * export, export_item_t * item, char * path, char * ext, int index) { char track[MAXLEN]; char buf[3*MAXLEN]; char str_no[16]; char str_index[16]; track[0] = '\0'; buf[0] = '\0'; strcat(buf, export->outdir); if (export->dir_for_artist) { strcat(buf, "/"); strcat(buf, export_map_put(&export->artist_map, item->artist, export->dir_len_limit)); if (!is_dir(buf) && mkdir(buf, S_IRUSR | S_IWUSR | S_IXUSR) < 0) { fprintf(stderr, "mkdir: %s: %s\n", buf, strerror(errno)); return -1; } } if (export->dir_for_album) { strcat(buf, "/"); strcat(buf, export_map_put(&export->record_map, item->album, export->dir_len_limit)); if (!is_dir(buf) && mkdir(buf, S_IRUSR | S_IWUSR | S_IXUSR) < 0) { fprintf(stderr, "mkdir: %s: %s\n", buf, strerror(errno)); return -1; } } snprintf(str_no, 15, "%02d", item->no); snprintf(str_index, 15, "%04d", index); make_string_va(track, export->template, 'a', item->artist, 'r', item->album, 't', item->title, 'n', str_no, 'x', ext, 'i', str_index, 0); snprintf(path, MAXLEN-1, "%s/%s", buf, track); return 0; } gboolean update_progbar_ratio(gpointer user_data) { export_t * export = (export_t *)user_data; if (export->slot) { char tmp[16]; AQUALUNG_MUTEX_LOCK(export->mutex); snprintf(tmp, 15, "%d%%", (int)(export->ratio * 100)); gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(export->progbar), export->ratio); AQUALUNG_MUTEX_UNLOCK(export->mutex); gtk_progress_bar_set_text(GTK_PROGRESS_BAR(export->progbar), tmp); } return TRUE; } gboolean set_prog_src_file_entry_idle(gpointer user_data) { export_t * export = (export_t *)user_data; if (export->slot) { char * utf8 = NULL; AQUALUNG_MUTEX_LOCK(export->mutex); utf8 = g_filename_display_name(export->file1); AQUALUNG_MUTEX_UNLOCK(export->mutex); gtk_entry_set_text(GTK_ENTRY(export->prog_file_entry1), utf8); gtk_widget_grab_focus(export->prog_cancel_button); g_free(utf8); } return FALSE; } gboolean set_prog_trg_file_entry_idle(gpointer user_data) { export_t * export = (export_t *)user_data; if (export->slot) { char * utf8 = NULL; AQUALUNG_MUTEX_LOCK(export->mutex); utf8 = g_filename_display_name(export->file2); AQUALUNG_MUTEX_UNLOCK(export->mutex); gtk_entry_set_text(GTK_ENTRY(export->prog_file_entry2), utf8); gtk_widget_grab_focus(export->prog_cancel_button); g_free(utf8); } return FALSE; } void set_prog_src_file_entry(export_t * export, char * file) { AQUALUNG_MUTEX_LOCK(export->mutex); strncpy(export->file1, file, MAXLEN-1); AQUALUNG_MUTEX_UNLOCK(export->mutex); aqualung_idle_add(set_prog_src_file_entry_idle, export); } void set_prog_trg_file_entry(export_t * export, char * file) { AQUALUNG_MUTEX_LOCK(export->mutex); strncpy(export->file2, file, MAXLEN-1); AQUALUNG_MUTEX_UNLOCK(export->mutex); aqualung_idle_add(set_prog_trg_file_entry_idle, export); } void export_meta_amend_frame(metadata_t * meta, int tag, int type, export_item_t * item) { char * str; meta_frame_t * frame; /* see whether particular frame type is available in this tag */ if (!meta_get_fieldname_embedded(tag, type, &str)) { return; } /* if yes, check for existence */ frame = metadata_get_frame_by_tag_and_type(meta, tag, type, NULL); if (frame != NULL) { return; } /* not found, add it with content from export item */ frame = meta_frame_new(); frame->tag = tag; frame->type = type; switch (type) { case META_FIELD_TITLE: frame->field_val = strdup(item->title); break; case META_FIELD_ARTIST: frame->field_val = strdup(item->artist); break; case META_FIELD_ALBUM: frame->field_val = strdup(item->album); break; case META_FIELD_DATE: { char str_year[6]; snprintf(str_year, 5, "%d", item->year); frame->field_val = strdup(str_year); } break; case META_FIELD_TRACKNO: frame->int_val = item->no; break; } metadata_add_frame(meta, frame); } /* Add metadata fields stored in Music Store / Playlist * if they were not transferred from source file metadata. */ void export_meta_amend_stored_fields(metadata_t * meta, int tags, export_item_t * item) { int tag = META_TAG_MAX; /* iterate on possible output tags */ while (tag) { if ((tags & tag) == 0) { tag >>= 1; continue; } if (strcmp(item->title, _("Unknown Track")) != 0) { export_meta_amend_frame(meta, tag, META_FIELD_TITLE, item); } if (strcmp(item->artist, _("Unknown Artist")) != 0) { export_meta_amend_frame(meta, tag, META_FIELD_ARTIST, item); } if (strcmp(item->album, _("Unknown Album")) != 0) { export_meta_amend_frame(meta, tag, META_FIELD_ALBUM, item); } if (item->year != 0) { export_meta_amend_frame(meta, tag, META_FIELD_DATE, item); } if (item->no != 0) { export_meta_amend_frame(meta, tag, META_FIELD_TRACKNO, item); } tag >>= 1; } } void export_item(export_t * export, export_item_t * item, int index) { file_decoder_t * fdec; file_encoder_t * fenc; encoder_mode_t mode; char * ext = "raw"; char filename[MAXLEN]; int tags = 0; int force_copy = 0; float buf[2*BUFSIZE]; int n_read; long long samples_read = 0; memset(&mode, 0, sizeof(encoder_mode_t)); switch (export->format) { case ENC_SNDFILE_LIB: ext = "wav"; tags = 0; break; case ENC_FLAC_LIB: ext = "flac"; #ifdef HAVE_FLAC_8 tags = META_TAG_OXC | META_TAG_FLAC_APIC; #else tags = META_TAG_OXC; #endif /* HAVE_FLAC_8 */ break; case ENC_VORBIS_LIB: ext = "ogg"; tags = META_TAG_OXC; break; case ENC_LAME_LIB: ext = "mp3"; tags = META_TAG_ID3v1 | META_TAG_ID3v2 | META_TAG_APE; break; } fdec = file_decoder_new(); if (file_decoder_open(fdec, item->infile)) { return; } if (export->filter_same) { if ((fdec->file_lib == FLAC_LIB && export->format == ENC_FLAC_LIB) || (fdec->file_lib == VORBIS_LIB && export->format == ENC_VORBIS_LIB) || (fdec->file_lib == MAD_LIB && export->format == ENC_LAME_LIB)) { force_copy = 1; } } if (export->excl_enabled) { char * utf8 = g_filename_display_name(item->infile); int i; for (i = 0; export->excl_patternv[i]; i++) { if (*(export->excl_patternv[i]) == '\0') { continue; } if (fnmatch(export->excl_patternv[i], utf8, FNM_CASEFOLD) == 0) { force_copy = 1; break; } } g_free(utf8); } if (force_copy || export->format == ENC_COPY) { if ((ext = strrchr(item->infile, '.')) == NULL) { ext = ""; } else { ++ext; } } if (export_item_set_path(export, item, filename, ext, index) < 0) { file_decoder_close(fdec); file_decoder_delete(fdec); return; } set_prog_src_file_entry(export, item->infile); set_prog_trg_file_entry(export, filename); if (force_copy || export->format == ENC_COPY) { char buf[BUFSIZE]; size_t n_read; struct stat statbuf; unsigned long pos = 0; int n = 0; FILE * fi; FILE * fo; file_decoder_close(fdec); file_decoder_delete(fdec); if (g_stat(item->infile, &statbuf) != -1) { if (statbuf.st_size == 0) { return; } } if ((fi = fopen(item->infile, "rb")) == NULL) { fprintf(stdout, "export_item: unable to open file %s\n", item->infile); return; } if ((fo = fopen(filename, "wb")) == NULL) { fclose(fi); fprintf(stdout, "export_item: unable to open file %s\n", filename); return; } while ((n_read = fread(buf, sizeof(char), sizeof(buf), fi)) > 0 && !export->cancelled) { fwrite(buf, sizeof(char), n_read, fo); pos += n_read; if (n-- == 0) { n = 100; AQUALUNG_MUTEX_LOCK(export->mutex); export->ratio = (double)pos / statbuf.st_size; AQUALUNG_MUTEX_UNLOCK(export->mutex); } } fclose(fi); fclose(fo); return; } strncpy(mode.filename, filename, MAXLEN-1); mode.file_lib = export->format; mode.sample_rate = fdec->fileinfo.sample_rate; mode.channels = fdec->fileinfo.channels; if (mode.file_lib == ENC_FLAC_LIB) { mode.clevel = export->bitrate; } else if (mode.file_lib == ENC_VORBIS_LIB) { mode.bps = export->bitrate * 1000; } else if (mode.file_lib == ENC_LAME_LIB) { mode.bps = export->bitrate * 1000; mode.vbr = export->vbr; } mode.write_meta = export->write_meta; if (mode.write_meta) { if (fdec->meta == NULL) { mode.meta = metadata_new(); } else { mode.meta = metadata_clone(fdec->meta, tags); } export_meta_amend_stored_fields(mode.meta, tags, item); } fenc = file_encoder_new(); if (file_encoder_open(fenc, &mode)) { return; } while (!export->cancelled) { n_read = file_decoder_read(fdec, buf, BUFSIZE); file_encoder_write(fenc, buf, n_read); samples_read += n_read; AQUALUNG_MUTEX_LOCK(export->mutex); export->ratio = (double)samples_read / fdec->fileinfo.total_samples; AQUALUNG_MUTEX_UNLOCK(export->mutex); if (n_read < BUFSIZE) { break; } } file_decoder_close(fdec); file_encoder_close(fenc); file_decoder_delete(fdec); file_encoder_delete(fenc); if (mode.meta != NULL) { metadata_free(mode.meta); } } void * export_thread(void * arg) { export_t * export = (export_t *)arg; GSList * node; int index = 0; AQUALUNG_THREAD_DETACH(); for (node = export->slist; node; node = node->next) { if (export->cancelled) { break; } ++index; export_item(export, (export_item_t *)node->data, index); } aqualung_idle_add(export_finish, export); return NULL; } void export_browse_cb(GtkButton * button, gpointer data) { file_chooser_with_entry(_("Please select the directory for exported files."), browser_window, GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, FILE_CHOOSER_FILTER_NONE, (GtkWidget *)data, options.exportdir); } GtkWidget * export_create_format_combo(void) { GtkWidget * combo = gtk_combo_box_new_text(); int n = -1; #ifdef HAVE_SNDFILE gtk_combo_box_append_text(GTK_COMBO_BOX(combo), "WAV"); ++n; #endif /* HAVE_SNDFILE */ #ifdef HAVE_FLAC gtk_combo_box_append_text(GTK_COMBO_BOX(combo), "FLAC"); ++n; #endif /* HAVE_FLAC */ #ifdef HAVE_VORBISENC gtk_combo_box_append_text(GTK_COMBO_BOX(combo), "Ogg Vorbis"); ++n; #endif /* HAVE_VORBISENC */ #ifdef HAVE_LAME gtk_combo_box_append_text(GTK_COMBO_BOX(combo), "MP3"); ++n; #endif /* HAVE_LAME */ gtk_combo_box_append_text(GTK_COMBO_BOX(combo), _("Copy")); ++n; if (n >= options.export_file_format) { gtk_combo_box_set_active(GTK_COMBO_BOX(combo), options.export_file_format); } else { gtk_combo_box_set_active(GTK_COMBO_BOX(combo), 0); } return combo; } /* returns file_lib value */ int export_get_format_from_combo(GtkWidget * combo) { int file_lib = -1; gchar * text = gtk_combo_box_get_active_text(GTK_COMBO_BOX(combo)); if (strcmp(text, "WAV") == 0) { file_lib = ENC_SNDFILE_LIB; } if (strcmp(text, "FLAC") == 0) { file_lib = ENC_FLAC_LIB; } if (strcmp(text, "Ogg Vorbis") == 0) { file_lib = ENC_VORBIS_LIB; } if (strcmp(text, "MP3") == 0) { file_lib = ENC_LAME_LIB; } if (strcmp(text, _("Copy")) == 0) { file_lib = ENC_COPY; } g_free(text); return file_lib; } void export_format_combo_changed(GtkWidget * widget, gpointer data) { export_t * export = (export_t *)data; gchar * text = gtk_combo_box_get_active_text(GTK_COMBO_BOX(widget)); if (strcmp(text, "WAV") == 0 || strcmp(text, _("Copy")) == 0) { gtk_widget_hide(export->bitrate_scale); gtk_widget_hide(export->bitrate_label); gtk_widget_hide(export->bitrate_value_label); gtk_widget_hide(export->vbr_check); gtk_widget_hide(export->meta_check); } if (strcmp(text, "FLAC") == 0) { gtk_widget_show(export->bitrate_scale); gtk_widget_show(export->bitrate_label); gtk_label_set_text(GTK_LABEL(export->bitrate_label), _("Compression level:")); gtk_widget_show(export->bitrate_value_label); gtk_widget_hide(export->vbr_check); gtk_widget_show(export->meta_check); gtk_range_set_range(GTK_RANGE(export->bitrate_scale), 0, 8); gtk_range_set_value(GTK_RANGE(export->bitrate_scale), options.export_bitrate); } if (strcmp(text, "Ogg Vorbis") == 0) { gtk_widget_show(export->bitrate_scale); gtk_widget_show(export->bitrate_label); gtk_label_set_text(GTK_LABEL(export->bitrate_label), _("Bitrate [kbps]:")); gtk_widget_show(export->bitrate_value_label); gtk_widget_hide(export->vbr_check); gtk_widget_show(export->meta_check); gtk_range_set_range(GTK_RANGE(export->bitrate_scale), 32, 320); gtk_range_set_value(GTK_RANGE(export->bitrate_scale), options.export_bitrate); } if (strcmp(text, "MP3") == 0) { gtk_widget_show(export->bitrate_scale); gtk_widget_show(export->bitrate_label); gtk_label_set_text(GTK_LABEL(export->bitrate_label), _("Bitrate [kbps]:")); gtk_widget_show(export->bitrate_value_label); gtk_widget_show(export->vbr_check); gtk_widget_show(export->meta_check); gtk_range_set_range(GTK_RANGE(export->bitrate_scale), 32, 320); gtk_range_set_value(GTK_RANGE(export->bitrate_scale), options.export_bitrate); } options.export_file_format = export_get_format_from_combo(widget); g_free(text); } void export_bitrate_changed(GtkRange * range, gpointer data) { export_t * export = (export_t *)data; float val = gtk_range_get_value(range); gchar * text = gtk_combo_box_get_active_text(GTK_COMBO_BOX(export->format_combo)); if (strcmp(text, "FLAC") == 0) { int i = (int)val; char str[256]; switch (i) { case 0: case 8: snprintf(str, 255, "%d (%s)", i, (i == 0) ? _("fast") : _("best")); gtk_label_set_text(GTK_LABEL(export->bitrate_value_label), str); break; default: snprintf(str, 255, "%d", i); gtk_label_set_text(GTK_LABEL(export->bitrate_value_label), str); break; } } if (strcmp(text, "Ogg Vorbis") == 0) { int i = (int)val; char str[256]; snprintf(str, 255, "%d", i); gtk_label_set_text(GTK_LABEL(export->bitrate_value_label), str); } if (strcmp(text, "MP3") == 0) { int i = (int)val; char str[256]; #ifdef HAVE_LAME i = lame_encoder_validate_bitrate(i, 0); #endif /* HAVE_LAME */ snprintf(str, 255, "%d", i); gtk_label_set_text(GTK_LABEL(export->bitrate_value_label), str); } g_free(text); } void check_dir_limit_toggled(GtkToggleButton * toggle, gpointer data) { export_t * export = (export_t *)data; if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(export->check_dir_artist)) || gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(export->check_dir_album))) { gtk_widget_set_sensitive(export->dirlen_spin, TRUE); } else { gtk_widget_set_sensitive(export->dirlen_spin, FALSE); } } void export_format_help_cb(GtkButton * button, gpointer user_data) { message_dialog(_("Help"), ((export_t *)user_data)->dialog, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, NULL, _("\nThe template string you enter here will be used to " "construct the filename of the exported files. The Artist, " "Record and Track names are denoted by %%%%a, %%%%r and %%%%t. " "The track number and format-dependent file extension are " "denoted by %%%%n and %%%%x, respectively. The flag %%%%i gives " "an identifier which is unique within an export session.")); } void export_check_excl_toggled(GtkWidget * widget, gpointer data) { gboolean state = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); gtk_widget_set_sensitive((GtkWidget *)data, state); } int export_dialog(export_t * export) { GtkWidget * help_button; GtkWidget * outdir_entry; GtkWidget * templ_entry; GtkWidget * table; GtkWidget * hbox; GtkWidget * frame; GtkWidget * check_filter_same; GtkWidget * check_excl_enabled; GtkWidget * excl_entry; export->dialog = gtk_dialog_new_with_buttons(_("Export files"), GTK_WINDOW(browser_window), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL); gtk_window_set_position(GTK_WINDOW(export->dialog), GTK_WIN_POS_CENTER); gtk_window_set_default_size(GTK_WINDOW(export->dialog), 400, -1); gtk_dialog_set_default_response(GTK_DIALOG(export->dialog), GTK_RESPONSE_REJECT); /* Location and filename */ frame = gtk_frame_new(_("Location and filename")); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(export->dialog)->vbox), frame, FALSE, FALSE, 2); gtk_container_set_border_width(GTK_CONTAINER(frame), 5); table = gtk_table_new(5, 2, FALSE); gtk_container_add(GTK_CONTAINER(frame), table); insert_label_entry_browse(table, _("Target directory:"), &outdir_entry, options.exportdir, 0, 1, export_browse_cb); export->check_dir_artist = gtk_check_button_new_with_label(_("Create subdirectories for artists")); gtk_widget_set_name(export->check_dir_artist, "check_on_notebook"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(export->check_dir_artist), options.export_subdir_artist); gtk_table_attach(GTK_TABLE(table), export->check_dir_artist, 0, 3, 1, 2, GTK_FILL, GTK_FILL, 5, 5); g_signal_connect(G_OBJECT(export->check_dir_artist), "toggled", G_CALLBACK(check_dir_limit_toggled), export); export->check_dir_album = gtk_check_button_new_with_label(_("Create subdirectories for albums")); gtk_widget_set_name(export->check_dir_album, "check_on_notebook"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(export->check_dir_album), options.export_subdir_album); gtk_table_attach(GTK_TABLE(table), export->check_dir_album, 0, 3, 2, 3, GTK_FILL, GTK_FILL, 5, 5); g_signal_connect(G_OBJECT(export->check_dir_album), "toggled", G_CALLBACK(check_dir_limit_toggled), export); insert_label_spin_with_limits(table, _("Subdirectory name\nlength limit:"), &export->dirlen_spin, options.export_subdir_limit, 4, 64, 3, 4); gtk_widget_set_sensitive(export->dirlen_spin, options.export_subdir_artist || options.export_subdir_album); help_button = gtk_button_new_from_stock(GTK_STOCK_HELP); g_signal_connect(help_button, "clicked", G_CALLBACK(export_format_help_cb), export); insert_label_entry_button(table, _("Filename template:"), &templ_entry, options.export_template, help_button, 4, 5); /* Format */ frame = gtk_frame_new(_("Format")); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(export->dialog)->vbox), frame, FALSE, FALSE, 2); gtk_container_set_border_width(GTK_CONTAINER(frame), 5); table = gtk_table_new(4, 2, TRUE); gtk_container_add(GTK_CONTAINER(frame), table); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), gtk_label_new(_("File format:")), FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(table), hbox, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 5, 4); export->format_combo = export_create_format_combo(); g_signal_connect(G_OBJECT(export->format_combo), "changed", G_CALLBACK(export_format_combo_changed), export); gtk_table_attach(GTK_TABLE(table), export->format_combo, 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 5, 2); hbox = gtk_hbox_new(FALSE, 0); export->bitrate_label = gtk_label_new(_("Compression level:")); gtk_box_pack_start(GTK_BOX(hbox), export->bitrate_label, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(table), hbox, 0, 1, 1, 2, GTK_FILL, GTK_FILL, 5, 0); export->bitrate_scale = gtk_hscale_new_with_range(0, 8, 1); g_signal_connect(G_OBJECT(export->bitrate_scale), "value-changed", G_CALLBACK(export_bitrate_changed), export); gtk_scale_set_draw_value(GTK_SCALE(export->bitrate_scale), FALSE); gtk_scale_set_digits(GTK_SCALE(export->bitrate_scale), 0); gtk_widget_set_size_request(export->bitrate_scale, 180, -1); gtk_table_attach(GTK_TABLE(table), export->bitrate_scale, 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, GTK_FILL, 5, 0); export->bitrate_value_label = gtk_label_new("0 (fast)"); gtk_table_attach(GTK_TABLE(table), export->bitrate_value_label, 1, 2, 2, 3, GTK_EXPAND | GTK_FILL, GTK_FILL, 5, 0); export->vbr_check = gtk_check_button_new_with_label(_("VBR encoding")); gtk_widget_set_name(export->vbr_check, "check_on_notebook"); gtk_table_attach(GTK_TABLE(table), export->vbr_check, 0, 1, 2, 3, GTK_FILL, GTK_FILL, 5, 0); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(export->vbr_check), options.export_vbr); export->meta_check = gtk_check_button_new_with_label(_("Tag files with metadata")); gtk_widget_set_name(export->meta_check, "check_on_notebook"); gtk_table_attach(GTK_TABLE(table), export->meta_check, 0, 2, 3, 4, GTK_EXPAND | GTK_FILL, GTK_FILL, 5, 4); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(export->meta_check), options.export_metadata); /* Filter */ frame = gtk_frame_new(_("Filter")); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(export->dialog)->vbox), frame, FALSE, FALSE, 2); gtk_container_set_border_width(GTK_CONTAINER(frame), 5); table = gtk_table_new(1, 2, FALSE); gtk_container_add(GTK_CONTAINER(frame), table); check_filter_same = gtk_check_button_new_with_label(_("Do not reencode files already being in the target format")); gtk_widget_set_name(check_filter_same, "check_on_notebook"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_filter_same), options.export_filter_same); gtk_table_attach(GTK_TABLE(table), check_filter_same, 0, 2, 0, 1, GTK_FILL, GTK_FILL, 5, 5); check_excl_enabled = gtk_check_button_new_with_label(_("Do not reencode files\nmatching wildcard:")); gtk_widget_set_name(check_excl_enabled, "check_on_notebook"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_excl_enabled), options.export_excl_enabled); gtk_table_attach(GTK_TABLE(table), check_excl_enabled, 0, 1, 1, 2, GTK_FILL, GTK_FILL, 5, 5); excl_entry = gtk_entry_new(); gtk_entry_set_max_length(GTK_ENTRY(excl_entry), MAXLEN-1); gtk_entry_set_text(GTK_ENTRY(excl_entry), options.export_excl_pattern); gtk_table_attach(GTK_TABLE(table), excl_entry, 1, 2, 1, 2, GTK_FILL, GTK_FILL, 5, 5); gtk_widget_set_sensitive(excl_entry, options.export_excl_enabled); g_signal_connect(G_OBJECT(check_excl_enabled), "toggled", G_CALLBACK(export_check_excl_toggled), excl_entry); gtk_widget_show_all(export->dialog); export_format_combo_changed(export->format_combo, export); display: export->outdir[0] = '\0'; if (aqualung_dialog_run(GTK_DIALOG(export->dialog)) == GTK_RESPONSE_ACCEPT) { char * poutdir = g_filename_from_utf8(gtk_entry_get_text(GTK_ENTRY(outdir_entry)), -1, NULL, NULL, NULL); if ((poutdir == NULL) || (poutdir[0] == '\0')) { gtk_widget_grab_focus(outdir_entry); g_free(poutdir); goto display; } normalize_filename(poutdir, export->outdir); g_free(poutdir); if (strlen(gtk_entry_get_text(GTK_ENTRY(templ_entry))) == 0) { gtk_widget_grab_focus(templ_entry); goto display; } else { int ret; char buf[MAXLEN]; char * format = (char *)gtk_entry_get_text(GTK_ENTRY(templ_entry)); if ((ret = make_string_va(buf, format, 'a', "a", 'r', "r", 't', "t", 'n', "n", 'x', "x", 'i', "i", 0)) != 0) { make_string_strerror(ret, buf); message_dialog(_("Error in format string"), export->dialog, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, NULL, buf); goto display; } } if (access(export->outdir, R_OK | W_OK) != 0) { message_dialog(_("Error"), export->dialog, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, NULL, _("\nDestination directory is not read-write accessible!")); gtk_widget_grab_focus(outdir_entry); goto display; } strncpy(options.exportdir, export->outdir, MAXLEN-1); set_option_from_entry(templ_entry, export->template, MAXLEN); set_option_from_entry(templ_entry, options.export_template, MAXLEN); options.export_file_format = export->format = export_get_format_from_combo(export->format_combo); options.export_bitrate = export->bitrate = gtk_range_get_value(GTK_RANGE(export->bitrate_scale)); set_option_from_toggle(export->check_dir_artist, &options.export_subdir_artist); set_option_from_toggle(export->check_dir_album, &options.export_subdir_album); set_option_from_spin(export->dirlen_spin, &options.export_subdir_limit); set_option_from_toggle(export->vbr_check, &export->vbr); options.export_vbr = export->vbr; set_option_from_toggle(export->meta_check, &export->write_meta); options.export_metadata = export->write_meta; set_option_from_toggle(export->check_dir_artist, &export->dir_for_artist); set_option_from_toggle(export->check_dir_album, &export->dir_for_album); set_option_from_toggle(check_filter_same, &export->filter_same); options.export_filter_same = export->filter_same; set_option_from_toggle(check_excl_enabled, &export->excl_enabled); options.export_excl_enabled = export->excl_enabled; if (export->excl_enabled) { set_option_from_entry(excl_entry, options.export_excl_pattern, MAXLEN); export->excl_patternv = g_strsplit(gtk_entry_get_text(GTK_ENTRY(excl_entry)), ",", 0); } if (export->dir_for_artist || export->dir_for_album) { set_option_from_spin(export->dirlen_spin, &export->dir_len_limit); } else { export->dir_len_limit = MAXLEN-1; } gtk_widget_destroy(export->dialog); return 1; } else { gtk_widget_destroy(export->dialog); return 0; } } gboolean export_window_event(GtkWidget * widget, GdkEvent * event, gpointer * data) { if (event->type == GDK_DELETE) { gtk_window_iconify(GTK_WINDOW(export_window)); return TRUE; } return FALSE; } void export_cancel_event(GtkButton * button, gpointer data) { export_t * export = (export_t *)data; export->cancelled = 1; } void create_export_window() { GtkWidget * vbox; export_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); register_toplevel_window(export_window, TOP_WIN_SKIN | TOP_WIN_TRAY); gtk_window_set_title(GTK_WINDOW(export_window), _("Exporting files")); gtk_window_set_position(GTK_WINDOW(export_window), GTK_WIN_POS_CENTER); gtk_window_resize(GTK_WINDOW(export_window), 480, 110); g_signal_connect(G_OBJECT(export_window), "event", G_CALLBACK(export_window_event), NULL); gtk_container_set_border_width(GTK_CONTAINER(export_window), 5); vbox = gtk_vbox_new(FALSE, 0); gtk_container_add(GTK_CONTAINER(export_window), vbox); gtk_widget_show_all(export_window); } void export_progress_window(export_t * export) { GtkWidget * vbox; ++export_slot_count; if (export_window == NULL) { create_export_window(); } vbox = gtk_bin_get_child(GTK_BIN(export_window)); export->slot = gtk_table_new(5, 2, FALSE); gtk_box_pack_start(GTK_BOX(vbox), export->slot, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(export->slot), gtk_hseparator_new(), 0, 2, 0, 1, GTK_FILL, GTK_FILL, 5, 5); insert_label_entry(export->slot, _("Source file:"), &export->prog_file_entry1, NULL, 1, 2, FALSE); insert_label_entry(export->slot, _("Target file:"), &export->prog_file_entry2, NULL, 2, 3, FALSE); export->prog_cancel_button = gui_stock_label_button(_("Abort"), GTK_STOCK_CANCEL); g_signal_connect(export->prog_cancel_button, "clicked", G_CALLBACK(export_cancel_event), export); insert_label_progbar_button(export->slot, _("Progress:"), &export->progbar, export->prog_cancel_button, 3, 4); gtk_table_attach(GTK_TABLE(export->slot), gtk_hseparator_new(), 0, 2, 4, 5, GTK_FILL, GTK_FILL, 5, 5); gtk_widget_grab_focus(export->prog_cancel_button); gtk_widget_show_all(export->slot); } int export_start(export_t * export) { if (export_dialog(export)) { export_progress_window(export); export->progbar_tag = aqualung_timeout_add(250, update_progbar_ratio, export); AQUALUNG_THREAD_CREATE(export->thread_id, NULL, export_thread, export); return 1; } export_free(export); return 0; } #endif /* HAVE_EXPORT */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/ext_title_format.h0000644000175000001440000000231211324131225015413 00000000000000/* -*- linux-c -*- Copyright (C) 2008 Jeremy Evans This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id$ */ #ifndef _EXT_TITLE_FORMAT_H #define _EXT_TITLE_FORMAT_H #include "decoder/file_decoder.h" void setup_extended_title_formatting(void); /* Caller responsible for freeing returned pointer for these methods: */ char * extended_title_format(file_decoder_t * fdec); char * application_title_format(file_decoder_t * fdec); #endif /* _EXT_TITLE_FORMAT_H */ // vim: shiftwidth=8:tabstop=8:softtabstop=8: aqualung-0.9beta11/src/ext_title_format.c0000644000175000001440000003640711324131225015422 00000000000000/* -*- linux-c -*- Copyright (C) 2008-2009 Jeremy Evans This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id$ */ #include "config.h" #ifdef HAVE_LUA #include #include #include #ifdef LUA_HEADER_lua5_1 #include #include #include #else #include #include #include #endif /* LUA_HEADER_DIR */ #include "metadata.h" #include "decoder/file_decoder.h" #include "options.h" #define AQUALUNG_LUA_APPLICATION_TITLE_FUNCTION "application_title" #define AQUALUNG_LUA_TITLE_FORMAT_FUNCTION "playlist_title" #define AQUALUNG_LUA_METADATA_FUNCTION "m" #define AQUALUNG_LUA_FILEINFO_FUNCTION "i" #define FILEINFO_TYPE_FILENAME 0x1 #define FILEINFO_TYPE_SAMPLE_RATE 0x2 #define FILEINFO_TYPE_CHANNELS 0x3 #define FILEINFO_TYPE_BPS 0x4 #define FILEINFO_TYPE_SAMPLES 0x5 #define FILEINFO_TYPE_VOLADJ_DB 0x6 #define FILEINFO_TYPE_VOLADJ_LIN 0x7 #define FILEINFO_TYPE_STREAM 0x8 #define FILEINFO_TYPE_MONO 0x9 extern options_t options; static lua_State * L = NULL; static GMutex * l_mutex = NULL; static const char l_cur_fdec = 'l'; /* Glib hash tables are abused as we store ints instead of pointers for the values */ static GHashTable * metadata_type_hash = NULL; static GHashTable * fileinfo_type_hash = NULL; int metadata_type_int(char * type_string) { return (int)(long)g_hash_table_lookup(metadata_type_hash, type_string); } int fileinfo_type_int(char * type_string) { return (int)(long)g_hash_table_lookup(fileinfo_type_hash, type_string); } /* Caller is responsible for freeing returned string */ char * metadata_value_all(metadata_t * meta, int type) { int l = 0; int t = 0; char * news; char * s = NULL; char * tmp_str; meta_frame_t * mframe = NULL; while ((mframe = metadata_pref_frame_by_type(meta, type, mframe)) != NULL) { if (mframe->field_val != NULL) { tmp_str = mframe->field_val; l = strlen(tmp_str); } else { if ((l = asprintf(&tmp_str, "%f", mframe->float_val)) == -1) { tmp_str = NULL; goto metadata_value_all_cleanup; } l += 1; } if (s == NULL) { t = l + 1; if ((s = (char *)malloc(t)) == NULL) { goto metadata_value_all_cleanup; } s[0] = '\0'; } else { t += l + 3; if ((news = (char *)realloc(s, t)) == NULL) { goto metadata_value_all_cleanup; } s = news; strncat(s, ", ", 2); } strncat(s, tmp_str, l); if (mframe->field_val == NULL) { free(tmp_str); } } return s; metadata_value_all_cleanup: free(s); if (mframe->field_val == NULL) { free(tmp_str); } return NULL; } static file_decoder_t * l_get_cur_fdec(lua_State * L) { file_decoder_t * fdec; lua_pushlightuserdata(L, (void *)&l_cur_fdec); lua_gettable(L, LUA_REGISTRYINDEX); fdec = (file_decoder_t *)lua_touserdata(L, -1); if (fdec == NULL) { luaL_error(L, "Programmer error: Invalid file decoder registered with lua"); } return fdec; } static int l_metadata_value(lua_State * L) { char * s = NULL; int i; file_decoder_t * fdec; s = (char *)lua_tostring(L, 1); if((i = metadata_type_int(s)) == 0){ luaL_error(L, "Invalid tag field: %s", s); } lua_pop(L, 1); fdec = l_get_cur_fdec(L); if ((fdec->meta != NULL) && \ ((s = metadata_value_all(fdec->meta, i)) != NULL)) { lua_pushstring(L, s); free(s); } else { lua_pushstring(L, ""); } return 1; } static int l_fileinfo_value(lua_State * L) { char * s = NULL; int i; file_decoder_t * fdec; s = (char *)lua_tostring(L, 1); if((i = fileinfo_type_int(s)) == 0){ luaL_error(L, "Invalid tag field: %s", s); } lua_pop(L, 1); fdec = l_get_cur_fdec(L); switch (i) { case FILEINFO_TYPE_FILENAME: lua_pushstring(L, fdec->filename); break; case FILEINFO_TYPE_SAMPLE_RATE: lua_pushinteger(L, fdec->fileinfo.sample_rate); break; case FILEINFO_TYPE_CHANNELS: lua_pushinteger(L, fdec->fileinfo.channels); break; case FILEINFO_TYPE_BPS: lua_pushinteger(L, fdec->fileinfo.bps); break; case FILEINFO_TYPE_SAMPLES: lua_pushinteger(L, fdec->fileinfo.total_samples); break; case FILEINFO_TYPE_VOLADJ_DB: lua_pushnumber(L, fdec->voladj_db); break; case FILEINFO_TYPE_VOLADJ_LIN: lua_pushnumber(L, fdec->voladj_lin); break; case FILEINFO_TYPE_STREAM: lua_pushboolean(L, fdec->is_stream); break; case FILEINFO_TYPE_MONO: lua_pushboolean(L, fdec->fileinfo.is_mono); break; default: luaL_error(L, "Programmer error, fileinfo type not handled: %d", i); break; } return 1; } void setup_extended_title_formatting(void) { int error; if (options.ext_title_format_file[0] == '\0') { options.use_ext_title_format = 0; return; } options.use_ext_title_format = 1; if (l_mutex == NULL) { l_mutex = g_mutex_new(); } if (metadata_type_hash == NULL) { metadata_type_hash = g_hash_table_new(g_str_hash, g_str_equal); g_hash_table_insert(metadata_type_hash, "title", (gpointer)META_FIELD_TITLE); g_hash_table_insert(metadata_type_hash, "artist", (gpointer)META_FIELD_ARTIST); g_hash_table_insert(metadata_type_hash, "album", (gpointer)META_FIELD_ALBUM); g_hash_table_insert(metadata_type_hash, "date", (gpointer)META_FIELD_DATE); g_hash_table_insert(metadata_type_hash, "genre", (gpointer)META_FIELD_GENRE); g_hash_table_insert(metadata_type_hash, "trackno", (gpointer)META_FIELD_TRACKNO); g_hash_table_insert(metadata_type_hash, "comment", (gpointer)META_FIELD_COMMENT); g_hash_table_insert(metadata_type_hash, "disc", (gpointer)META_FIELD_DISC); g_hash_table_insert(metadata_type_hash, "performer", (gpointer)META_FIELD_PERFORMER); g_hash_table_insert(metadata_type_hash, "description", (gpointer)META_FIELD_DESCRIPTION); g_hash_table_insert(metadata_type_hash, "organization", (gpointer)META_FIELD_ORGANIZATION); g_hash_table_insert(metadata_type_hash, "location", (gpointer)META_FIELD_LOCATION); g_hash_table_insert(metadata_type_hash, "contact", (gpointer)META_FIELD_CONTACT); g_hash_table_insert(metadata_type_hash, "license", (gpointer)META_FIELD_LICENSE); g_hash_table_insert(metadata_type_hash, "copyright", (gpointer)META_FIELD_COPYRIGHT); g_hash_table_insert(metadata_type_hash, "isrc", (gpointer)META_FIELD_ISRC); g_hash_table_insert(metadata_type_hash, "version", (gpointer)META_FIELD_VERSION); g_hash_table_insert(metadata_type_hash, "subtitle", (gpointer)META_FIELD_SUBTITLE); g_hash_table_insert(metadata_type_hash, "debut_album", (gpointer)META_FIELD_DEBUT_ALBUM); g_hash_table_insert(metadata_type_hash, "publisher", (gpointer)META_FIELD_PUBLISHER); g_hash_table_insert(metadata_type_hash, "conductor", (gpointer)META_FIELD_CONDUCTOR); g_hash_table_insert(metadata_type_hash, "composer", (gpointer)META_FIELD_COMPOSER); g_hash_table_insert(metadata_type_hash, "publication_right", (gpointer)META_FIELD_PRIGHT); g_hash_table_insert(metadata_type_hash, "file", (gpointer)META_FIELD_FILE); g_hash_table_insert(metadata_type_hash, "ean_upc", (gpointer)META_FIELD_EAN_UPC); g_hash_table_insert(metadata_type_hash, "isbn", (gpointer)META_FIELD_ISBN); g_hash_table_insert(metadata_type_hash, "catalog", (gpointer)META_FIELD_CATALOG); g_hash_table_insert(metadata_type_hash, "label_code", (gpointer)META_FIELD_LC); g_hash_table_insert(metadata_type_hash, "record_date", (gpointer)META_FIELD_RECORD_DATE); g_hash_table_insert(metadata_type_hash, "record_location", (gpointer)META_FIELD_RECORD_LOC); g_hash_table_insert(metadata_type_hash, "media", (gpointer)META_FIELD_MEDIA); g_hash_table_insert(metadata_type_hash, "index", (gpointer)META_FIELD_INDEX); g_hash_table_insert(metadata_type_hash, "related", (gpointer)META_FIELD_RELATED); g_hash_table_insert(metadata_type_hash, "abstract", (gpointer)META_FIELD_ABSTRACT); g_hash_table_insert(metadata_type_hash, "language", (gpointer)META_FIELD_LANGUAGE); g_hash_table_insert(metadata_type_hash, "bibliography", (gpointer)META_FIELD_BIBLIOGRAPHY); g_hash_table_insert(metadata_type_hash, "introplay", (gpointer)META_FIELD_INTROPLAY); g_hash_table_insert(metadata_type_hash, "bpm", (gpointer)META_FIELD_TBPM); g_hash_table_insert(metadata_type_hash, "encoding_time", (gpointer)META_FIELD_TDEN); g_hash_table_insert(metadata_type_hash, "playlist_delay", (gpointer)META_FIELD_TDLY); g_hash_table_insert(metadata_type_hash, "original_release_time", (gpointer)META_FIELD_TDOR); g_hash_table_insert(metadata_type_hash, "release_time", (gpointer)META_FIELD_TDRL); g_hash_table_insert(metadata_type_hash, "tagging_time", (gpointer)META_FIELD_TDTG); g_hash_table_insert(metadata_type_hash, "encoded_by", (gpointer)META_FIELD_TENC); g_hash_table_insert(metadata_type_hash, "lyricist", (gpointer)META_FIELD_T_E_X_T); g_hash_table_insert(metadata_type_hash, "filetype", (gpointer)META_FIELD_TFLT); g_hash_table_insert(metadata_type_hash, "involved_people", (gpointer)META_FIELD_TIPL); g_hash_table_insert(metadata_type_hash, "content_group", (gpointer)META_FIELD_TIT1); g_hash_table_insert(metadata_type_hash, "initial_key", (gpointer)META_FIELD_TKEY); g_hash_table_insert(metadata_type_hash, "length", (gpointer)META_FIELD_TLEN); g_hash_table_insert(metadata_type_hash, "musician_credits", (gpointer)META_FIELD_TMCL); g_hash_table_insert(metadata_type_hash, "mood", (gpointer)META_FIELD_TMOO); g_hash_table_insert(metadata_type_hash, "original_album", (gpointer)META_FIELD_TOAL); g_hash_table_insert(metadata_type_hash, "original_filename", (gpointer)META_FIELD_TOFN); g_hash_table_insert(metadata_type_hash, "original_lyricist", (gpointer)META_FIELD_TOLY); g_hash_table_insert(metadata_type_hash, "original_artist", (gpointer)META_FIELD_TOPE); g_hash_table_insert(metadata_type_hash, "file_owner", (gpointer)META_FIELD_TOWN); g_hash_table_insert(metadata_type_hash, "band", (gpointer)META_FIELD_TPE2); g_hash_table_insert(metadata_type_hash, "remixed", (gpointer)META_FIELD_TPE4); g_hash_table_insert(metadata_type_hash, "set_part", (gpointer)META_FIELD_TPOS); g_hash_table_insert(metadata_type_hash, "produced", (gpointer)META_FIELD_TPRO); g_hash_table_insert(metadata_type_hash, "station_name", (gpointer)META_FIELD_TRSN); g_hash_table_insert(metadata_type_hash, "station_owner", (gpointer)META_FIELD_TRSO); g_hash_table_insert(metadata_type_hash, "album_order", (gpointer)META_FIELD_TSOA); g_hash_table_insert(metadata_type_hash, "performer_order", (gpointer)META_FIELD_TSOP); g_hash_table_insert(metadata_type_hash, "title_order", (gpointer)META_FIELD_TSOT); g_hash_table_insert(metadata_type_hash, "software", (gpointer)META_FIELD_TSSE); g_hash_table_insert(metadata_type_hash, "set_subtitle", (gpointer)META_FIELD_TSST); g_hash_table_insert(metadata_type_hash, "user_text", (gpointer)META_FIELD_TXXX); g_hash_table_insert(metadata_type_hash, "commercial_info", (gpointer)META_FIELD_WCOM); g_hash_table_insert(metadata_type_hash, "legal_info", (gpointer)META_FIELD_WCOP); g_hash_table_insert(metadata_type_hash, "file_website", (gpointer)META_FIELD_WOAF); g_hash_table_insert(metadata_type_hash, "artist_website", (gpointer)META_FIELD_WOAR); g_hash_table_insert(metadata_type_hash, "source_website", (gpointer)META_FIELD_WOAS); g_hash_table_insert(metadata_type_hash, "station_website", (gpointer)META_FIELD_WORS); g_hash_table_insert(metadata_type_hash, "payment", (gpointer)META_FIELD_WPAY); g_hash_table_insert(metadata_type_hash, "publisher_website", (gpointer)META_FIELD_WPUB); g_hash_table_insert(metadata_type_hash, "user_url", (gpointer)META_FIELD_WXXX); g_hash_table_insert(metadata_type_hash, "vendor", (gpointer)META_FIELD_VENDOR); g_hash_table_insert(metadata_type_hash, "rg_loudness", (gpointer)META_FIELD_RG_REFLOUDNESS); g_hash_table_insert(metadata_type_hash, "track_gain", (gpointer)META_FIELD_RG_TRACK_GAIN); g_hash_table_insert(metadata_type_hash, "track_peak", (gpointer)META_FIELD_RG_TRACK_PEAK); g_hash_table_insert(metadata_type_hash, "album_gain", (gpointer)META_FIELD_RG_ALBUM_GAIN); g_hash_table_insert(metadata_type_hash, "album_peak", (gpointer)META_FIELD_RG_ALBUM_PEAK); g_hash_table_insert(metadata_type_hash, "icy_name", (gpointer)META_FIELD_ICY_NAME); g_hash_table_insert(metadata_type_hash, "icy_descr", (gpointer)META_FIELD_ICY_DESCR); g_hash_table_insert(metadata_type_hash, "icy_genre", (gpointer)META_FIELD_ICY_GENRE); g_hash_table_insert(metadata_type_hash, "rva", (gpointer)META_FIELD_RVA2); fileinfo_type_hash = g_hash_table_new(g_str_hash, g_str_equal); g_hash_table_insert(fileinfo_type_hash, "filename", (gpointer)FILEINFO_TYPE_FILENAME); g_hash_table_insert(fileinfo_type_hash, "sample_rate", (gpointer)FILEINFO_TYPE_SAMPLE_RATE); g_hash_table_insert(fileinfo_type_hash, "channels", (gpointer)FILEINFO_TYPE_CHANNELS); g_hash_table_insert(fileinfo_type_hash, "bps", (gpointer)FILEINFO_TYPE_BPS); g_hash_table_insert(fileinfo_type_hash, "samples", (gpointer)FILEINFO_TYPE_SAMPLES); g_hash_table_insert(fileinfo_type_hash, "voladj_db", (gpointer)FILEINFO_TYPE_VOLADJ_DB); g_hash_table_insert(fileinfo_type_hash, "voladj_lin", (gpointer)FILEINFO_TYPE_VOLADJ_LIN); g_hash_table_insert(fileinfo_type_hash, "stream", (gpointer)FILEINFO_TYPE_STREAM); g_hash_table_insert(fileinfo_type_hash, "mono", (gpointer)FILEINFO_TYPE_MONO); } g_mutex_lock(l_mutex); if(L != NULL) { lua_close(L); } L = lua_open(); luaopen_base(L); luaopen_table(L); luaopen_string(L); luaopen_math(L); lua_pushcfunction(L, l_metadata_value); lua_setglobal(L, AQUALUNG_LUA_METADATA_FUNCTION); lua_pushcfunction(L, l_fileinfo_value); lua_setglobal(L, AQUALUNG_LUA_FILEINFO_FUNCTION); error = luaL_loadfile(L, options.ext_title_format_file) || lua_pcall(L, 0, 0, 0); if (error) { fprintf(stderr, "Error in setup_extended_title_formatting: %s\n", lua_tostring(L, -1)); options.use_ext_title_format = 0; lua_pop(L, 1); } g_mutex_unlock(l_mutex); } char * l_title_format(const char * function_name, file_decoder_t * fdec) { int error; char * s = NULL; if (options.use_ext_title_format) { g_mutex_lock(l_mutex); lua_pushlightuserdata(L, (void *)&l_cur_fdec); lua_pushlightuserdata(L, (void *)fdec); lua_settable(L, LUA_REGISTRYINDEX); lua_getglobal(L, function_name); error = lua_pcall(L, 0, 1, 0); if (error) { fprintf(stderr, "Error in l_title_format (%s): %s\n", function_name, lua_tostring(L, -1)); } else { s = strdup(lua_tostring(L, -1)); } lua_pop(L, 1); g_mutex_unlock(l_mutex); } return s; } char * extended_title_format(file_decoder_t * fdec) { return l_title_format(AQUALUNG_LUA_TITLE_FORMAT_FUNCTION, fdec); } char * application_title_format(file_decoder_t * fdec) { char * s = NULL; if ((s = l_title_format(AQUALUNG_LUA_APPLICATION_TITLE_FUNCTION, fdec)) == NULL) { s = l_title_format(AQUALUNG_LUA_TITLE_FORMAT_FUNCTION, fdec); } return s; } #endif /* HAVE_LUA */ aqualung-0.9beta11/src/file_info.h0000644000175000001440000000221310704513503014000 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: file_info.h 839 2007-10-14 21:56:03Z pasp $ */ #ifndef _FILE_INFO_H #define _FILE_INFO_H #include void show_file_info(char * name, char * file, int is_called_from_browser, GtkTreeModel * model, GtkTreeIter iter_track, gboolean cover_flag); #endif /* _FILE_INFO_H */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/file_info.c0000644000175000001440000021063211316415632014005 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: file_info.c 1088 2009-12-28 12:27:08Z peterszilagyi $ */ #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_MOD_INFO #include #endif /* HAVE_MOD_INFO */ #ifdef HAVE_MOD #include "decoder/dec_mod.h" #endif /* HAVE_MOD */ #ifdef HAVE_WAVPACK #include "decoder/dec_wavpack.h" #endif /* HAVE_WAVPACK */ #include "common.h" #include "utils.h" #include "utils_gui.h" #include "core.h" #include "cdda.h" #include "cover.h" #include "decoder/file_decoder.h" #include "music_browser.h" #include "store_file.h" #include "gui_main.h" #include "options.h" #include "trashlist.h" #include "i18n.h" #include "metadata_id3v1.h" #include "metadata_id3v2.h" #include "file_info.h" /* requested width of value display/edit widgets */ #define VAL_WIDGET_WIDTH 250 /* import destination codes */ enum { IMPORT_DEST_ARTIST, IMPORT_DEST_RECORD, IMPORT_DEST_TITLE, IMPORT_DEST_YEAR, IMPORT_DEST_NUMBER, IMPORT_DEST_COMMENT, IMPORT_DEST_RVA }; extern options_t options; extern GtkWidget* gui_stock_label_button(gchar *label, const gchar *stock); #define FI_MAXPAGES 256 typedef struct { int tag; GtkWidget * table; int n_rows; int n_cols; GtkWidget * combo; GSList * slist; /* list of insertable frames */ } pageidx_t; typedef struct { int is_called_from_browser; int bail_out; char * filename; file_decoder_t * fdec; metadata_t * meta; trashlist_t * trash; GtkTreeModel * model; GtkTreeIter track_iter; GtkWidget * info_window; GtkWidget * event_box; GtkWidget * cover_image_area; GtkWidget * cover_align; GtkWidget * hbox; GtkWidget * button_table; GtkWidget * save_button; GtkWidget * nb; GtkWidget * combo; int addable_tags; /* META_TAG_*, bitwise or-ed */ gint n_pages; /* number of notebook pages */ pageidx_t pageidx[FI_MAXPAGES]; int dirty; /* whether the dialog has unsaved changes */ /* for MOD info */ GtkWidget * smp_instr_list; GtkListStore * smp_instr_list_store; } fi_t; typedef struct { fi_t * fi; meta_frame_t * frame; int dest_type; /* one of IMPORT_DEST_* */ } import_data_t; typedef struct { fi_t * fi; char savefile[MAXLEN]; unsigned int image_size; void * image_data; GtkWidget * save_button; } save_pic_t; typedef struct { fi_t * fi; meta_frame_t * frame; save_pic_t * save_pic; } change_pic_t; /* 'source widget' for APIC frames */ typedef struct { GtkWidget * descr_entry; GtkWidget * type_combo; GtkWidget * mime_label; GtkWidget * image; } apic_source_t; extern GtkWidget * main_window; extern GtkTreeStore * music_store; extern GtkTreeSelection * music_select; extern GtkWidget * music_tree; #ifdef HAVE_MOD_INFO void module_info_fill_page(fi_t * fi, meta_frame_t * frame, GtkWidget * vbox); #endif /* HAVE_MOD_INFO */ gint fi_save(GtkWidget * widget, gpointer data); void fi_procframe_ins(fi_t * fi, meta_frame_t * frame); void fi_procframe_add_tag_page(fi_t * fi, meta_frame_t * frame); fi_t * fi_new(void) { fi_t * fi; int i; if ((fi = (fi_t *)calloc(1, sizeof(fi_t))) == NULL) { fprintf(stderr, "error: fileinfo_new(): calloc error\n"); return NULL; } for (i = 0; i < FI_MAXPAGES; i++) { fi->pageidx[i].tag = -1; } return fi; } void fi_delete(fi_t * fi) { int i; if (fi == NULL) return; if (fi->fdec != NULL) { file_decoder_delete(fi->fdec); } free(fi->filename); for (i = 0; i < FI_MAXPAGES; i++) { g_slist_free(fi->pageidx[i].slist); fi->pageidx[i].slist = NULL; } free(fi); } void fi_mark_changed(fi_t * fi) { if (fi->dirty != 0) return; gtk_window_set_title(GTK_WINDOW(fi->info_window), _("*File info")); fi->dirty = 1; } void fi_mark_unchanged(fi_t * fi) { if (fi->dirty == 0) return; gtk_window_set_title(GTK_WINDOW(fi->info_window), _("File info")); fi->dirty = 0; } import_data_t * import_data_new(void) { import_data_t * data; if ((data = (import_data_t *)calloc(1, sizeof(import_data_t))) == NULL) { fprintf(stderr, "error: import_data_new(): calloc error\n"); return NULL; } return data; } int fi_close_dialog(fi_t * fi) { int ret; GtkWidget * dialog = gtk_message_dialog_new(GTK_WINDOW(fi->info_window), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_WARNING, GTK_BUTTONS_NONE, _("There are unsaved changes to the file metadata.")); gtk_window_set_title(GTK_WINDOW(dialog), _("Warning")); gtk_dialog_add_buttons(GTK_DIALOG(dialog), _("Save and close"), 1, _("Discard changes"), 2, _("Do not close"), 0, NULL); gtk_dialog_set_default_response(GTK_DIALOG(dialog), 0); ret = aqualung_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); return ret; } int fi_can_close(fi_t * fi) { if (fi->dirty != 0) { switch (fi_close_dialog(fi)) { case 1: /* Save and close */ return fi_save(NULL, fi); case 2: /* Discard changes */ return TRUE; default: /* Do not close */ return FALSE; } } return TRUE; } gint dismiss(GtkWidget * widget, gpointer data) { fi_t * fi = (fi_t *)data; if (fi_can_close(fi) != TRUE) { return TRUE; } unregister_toplevel_window(fi->info_window); gtk_widget_destroy(fi->info_window); trashlist_free(fi->trash); fi_delete(fi); return TRUE; } gint info_window_close(GtkWidget * widget, GdkEventAny * event, gpointer data) { fi_t * fi = (fi_t *)data; if (fi_can_close(fi) != TRUE) { return TRUE; } unregister_toplevel_window(fi->info_window); gtk_widget_destroy(fi->info_window); trashlist_free(fi->trash); fi_delete(fi); return TRUE; } gint info_window_key_pressed(GtkWidget * widget, GdkEventKey * kevent, gpointer data) { fi_t * fi = (fi_t *)data; int page; switch (kevent->keyval) { case GDK_Escape: dismiss(NULL, data); return TRUE; break; case GDK_Return: page = (gtk_notebook_get_current_page(GTK_NOTEBOOK(fi->nb)) + 1) % fi->n_pages; gtk_notebook_set_current_page(GTK_NOTEBOOK(fi->nb), page); break; } return FALSE; } int fi_set_frame_from_source(fi_t * fi, meta_frame_t * frame) { char * parsefmt = meta_get_field_parsefmt(frame->type); char parsefmt_esc[MAXLEN]; escape_percents(parsefmt, parsefmt_esc); if (META_FIELD_TEXT(frame->type)) { if (frame->field_val != NULL) { free(frame->field_val); } if (frame->type == META_FIELD_GENRE) { frame->field_val = gtk_combo_box_get_active_text(GTK_COMBO_BOX(frame->source)); } else { frame->field_val = strdup(gtk_entry_get_text(GTK_ENTRY(frame->source))); } } else if (META_FIELD_INT(frame->type)) { int val = 0; const char * str = gtk_entry_get_text(GTK_ENTRY(frame->source)); if (sscanf(str, parsefmt, &val) < 1) { char msg[MAXLEN]; snprintf(msg, MAXLEN-1, _("Conversion error in field %s:\n" "'%s' does not conform to format '%s'!"), frame->field_name, str, "%s"); message_dialog(_("Error"), fi->info_window, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, NULL, msg, parsefmt_esc); return -1; } else { frame->int_val = val; } } else if (META_FIELD_FLOAT(frame->type)) { float val = 0; const char * str = gtk_entry_get_text(GTK_ENTRY(frame->source)); if (sscanf(str, parsefmt, &val) < 1) { char msg[MAXLEN]; snprintf(msg, MAXLEN-1, _("Conversion error in field %s:\n" "'%s' does not conform to format '%s'!"), frame->field_name, str, "%s"); message_dialog(_("Error"), fi->info_window, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, NULL, msg, parsefmt_esc); return -1; } else { frame->float_val = val; } } else if (META_FIELD_BIN(frame->type)) { if (frame->type == META_FIELD_APIC) { apic_source_t * source = (apic_source_t *)frame->source; if (frame->field_val != NULL) { free(frame->field_val); } frame->field_val = strdup(gtk_entry_get_text(GTK_ENTRY(source->descr_entry))); frame->int_val = gtk_combo_box_get_active(GTK_COMBO_BOX(source->type_combo)); if (frame->length == 0) { message_dialog(_("Error"), fi->info_window, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, NULL, _("Attached Picture frame with no image set!\n" "Please set an image or remove the frame.")); return -1; } } } return 0; } gint fi_save(GtkWidget * widget, gpointer data) { fi_t * fi = (fi_t *)data; metadata_t * meta = fi->meta; meta_frame_t * frame = meta->root; int status = 0; while (frame != NULL) { if (fi_set_frame_from_source(fi, frame) < 0) { status = -1; break; } frame = frame->next; } if (status != 0) { return FALSE; } if (fi->fdec->meta_write != NULL) { int ret; ret = fi->fdec->meta_write(fi->fdec, fi->meta); if (ret == META_ERROR_NONE) { fi_mark_unchanged(fi); return TRUE; } else { message_dialog(_("Error"), fi->info_window, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, NULL, _("Failed to write metadata to file.\n" "Reason: %s"), metadata_strerror(ret)); return FALSE; } } else { fprintf(stderr, "programmer error: fdec->meta_write == NULL\n"); } return FALSE; } void import_button_pressed(GtkWidget * widget, gpointer gptr_data) { import_data_t * data = (import_data_t *)gptr_data; fi_t * fi = data->fi; meta_frame_t * frame = data->frame; GtkTreeModel * model = fi->model; GtkTreeIter track_iter = fi->track_iter; GtkTreeIter record_iter; GtkTreeIter artist_iter; GtkTreePath * path; char tmp[MAXLEN]; record_data_t * record_data; track_data_t * track_data; if (fi_set_frame_from_source(fi, frame) < 0) { return; } switch (data->dest_type) { case IMPORT_DEST_TITLE: gtk_tree_store_set(music_store, &track_iter, MS_COL_NAME, frame->field_val, -1); music_store_mark_changed(&track_iter); break; case IMPORT_DEST_RECORD: gtk_tree_model_iter_parent(model, &record_iter, &track_iter); gtk_tree_store_set(music_store, &record_iter, MS_COL_NAME, frame->field_val, -1); music_store_mark_changed(&record_iter); break; case IMPORT_DEST_ARTIST: gtk_tree_model_iter_parent(model, &record_iter, &track_iter); gtk_tree_model_iter_parent(model, &artist_iter, &record_iter); gtk_tree_store_set(music_store, &artist_iter, MS_COL_NAME, frame->field_val, -1); gtk_tree_store_set(music_store, &artist_iter, MS_COL_SORT, frame->field_val, -1); path = gtk_tree_model_get_path(model, &track_iter); gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(music_tree), path, NULL, TRUE, 0.5f, 0.0f); music_store_mark_changed(&artist_iter); break; case IMPORT_DEST_YEAR: gtk_tree_model_iter_parent(model, &record_iter, &track_iter); gtk_tree_model_get(GTK_TREE_MODEL(music_store), &record_iter, MS_COL_DATA, &record_data, -1); if (sscanf(frame->field_val, "%d", &record_data->year) < 1) { char msg[MAXLEN]; snprintf(msg, MAXLEN-1, _("Error converting field %s to Year:\n" "'%s' is not an integer number!"), frame->field_name, frame->field_val); message_dialog(_("Error"), fi->info_window, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, NULL, msg); return; } else { music_store_mark_changed(&record_iter); } break; case IMPORT_DEST_NUMBER: snprintf(tmp, MAXLEN-1, "%02d", frame->int_val); gtk_tree_store_set(music_store, &track_iter, MS_COL_SORT, tmp, -1); music_store_mark_changed(&track_iter); break; case IMPORT_DEST_COMMENT: gtk_tree_model_get(model, &track_iter, MS_COL_DATA, &track_data, -1); tmp[0] = '\0'; if (track_data->comment != NULL) { strncat(tmp, track_data->comment, MAXLEN-1); } if ((tmp[strlen(tmp)-1] != '\n') && (tmp[0] != '\0')) { strncat(tmp, "\n", MAXLEN-1); } strncat(tmp, frame->field_val, MAXLEN-1); free_strdup(&track_data->comment, tmp); music_store_mark_changed(&track_iter); break; case IMPORT_DEST_RVA: gtk_tree_model_get(model, &track_iter, MS_COL_DATA, &track_data, -1); track_data->rva = frame->float_val; track_data->use_rva = 1; music_store_mark_changed(&track_iter); break; } } void fi_set_page(fi_t * fi) { fi->n_pages = gtk_notebook_get_n_pages(GTK_NOTEBOOK(fi->nb)); if (fi->n_pages > 1) { gtk_notebook_set_current_page(GTK_NOTEBOOK(fi->nb), options.tags_tab_first ? 1 : 0); } } int lookup_page(fi_t * fi, int tag) { int i; for (i = 0; i < FI_MAXPAGES; i++) { if (fi->pageidx[i].tag == tag) return i; } return -1; } int fi_tabwidth(fi_t * fi, metadata_t * meta) { /* tabwidth is 2, +1 if called from Music Store, +1 if editable */ int tabwidth = 2; tabwidth += fi->is_called_from_browser? 1 : 0; tabwidth += meta->writable ? 1 : 0; return tabwidth; } void save_pic_button_pressed(GtkWidget * widget, gpointer data) { save_pic_t * save_pic = (save_pic_t *)data; fi_t * fi = save_pic->fi; GSList * lfiles = NULL; char filename[MAXLEN]; char * dirname; dirname = g_path_get_dirname(options.currdir); snprintf(filename, MAXLEN-1, "%s/%s", dirname, save_pic->savefile); g_free(dirname); lfiles = file_chooser(_("Please specify the file to save the image to."), fi->info_window, GTK_FILE_CHOOSER_ACTION_SAVE, FILE_CHOOSER_FILTER_NONE, FALSE, filename); if (lfiles != NULL) { FILE * f = fopen(filename, "wb"); g_slist_free(lfiles); if (f == NULL) { fprintf(stderr, "error: fopen() failed\n"); return; } if (fwrite(save_pic->image_data, 1, save_pic->image_size, f) != save_pic->image_size) { fprintf(stderr, "fwrite() error\n"); return; } fclose(f); strncpy(options.currdir, filename, MAXLEN-1); } } void save_pic_update(save_pic_t * save_pic, fi_t * fi, meta_frame_t * frame) { int i, r; char mtype[20]; char savefilename[256]; mtype[0] = '\0'; strcpy(savefilename, "picture."); r = sscanf(frame->field_name, "image/%s", mtype); if (r == 0) { strncpy(mtype, frame->field_name, 19); } for (i = 0; mtype[i] != '\0'; i++) { mtype[i] = tolower(mtype[i]); } if (mtype[0] == '\0') { strcpy(mtype, "dat"); } strncat(savefilename, mtype, 255); save_pic->fi = fi; strncpy(save_pic->savefile, savefilename, MAXLEN-1); save_pic->image_size = frame->length; save_pic->image_data = frame->data; if (save_pic->image_size > 0) { gtk_widget_set_sensitive(save_pic->save_button, TRUE); } else { gtk_widget_set_sensitive(save_pic->save_button, FALSE); } } GtkWidget * make_image_from_binary(meta_frame_t * frame) { GdkPixbuf * pixbuf; GdkPixbuf * pixbuf_scaled; GtkWidget * image; int width, height; int new_width, new_height; void * data = frame->data; int length = frame->length; GdkPixbufLoader * loader; if (length == 0) { return gtk_label_new(_("(no image)")); } if (strcmp(frame->field_name, "-->") == 0) { /* display URL */ char * str = meta_id3v2_to_utf8(0x0/*ascii*/, data, length); GtkWidget * label = gtk_label_new(str); g_free(str); return label; } loader = gdk_pixbuf_loader_new(); if (gdk_pixbuf_loader_write(loader, frame->data, frame->length, NULL) != TRUE) { fprintf(stderr, "make_image_from_binary: failed to load image #1\n"); g_object_unref(loader); return gtk_label_new(_("(error loading image)")); } if (gdk_pixbuf_loader_close(loader, NULL) != TRUE) { fprintf(stderr, "make_image_from_binary: failed to load image #2\n"); g_object_unref(loader); return gtk_label_new(_("(error loading image)")); } pixbuf = gdk_pixbuf_loader_get_pixbuf(loader); width = gdk_pixbuf_get_width(pixbuf); height = gdk_pixbuf_get_height(pixbuf); new_width = (width > VAL_WIDGET_WIDTH) ? VAL_WIDGET_WIDTH : width; new_height = ((double)new_width / (double)width) * height; pixbuf_scaled = gdk_pixbuf_scale_simple(pixbuf, new_width, new_height, GDK_INTERP_BILINEAR); image = gtk_image_new_from_pixbuf(pixbuf_scaled); g_object_unref(pixbuf_scaled); g_object_unref(loader); return image; } void change_pic_button_pressed(GtkWidget * widget, gpointer data) { change_pic_t * change_pic = (change_pic_t *)data; save_pic_t * save_pic = change_pic->save_pic; fi_t * fi = change_pic->fi; meta_frame_t * frame = change_pic->frame; apic_source_t * source = ((apic_source_t *)(frame->source)); GSList * lfiles = NULL; char str[MAXLEN]; GdkPixbufFormat * pformat; gchar ** mime_types; GtkWidget * vbox; /* parent of image */ lfiles = file_chooser(_("Please specify the file to load the image from."), fi->info_window, GTK_FILE_CHOOSER_ACTION_OPEN, FILE_CHOOSER_FILTER_NONE, FALSE, options.currdir); if (lfiles != NULL) { g_slist_free(lfiles); } else { return; } pformat = gdk_pixbuf_get_file_info(options.currdir, NULL, NULL); if (pformat == NULL) { char msg[MAXLEN]; snprintf(msg, MAXLEN-1, _("Could not load image from:\n%s"), options.currdir); message_dialog(_("Error"), fi->info_window, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, NULL, msg); return; } if (frame->data != NULL) { free(frame->data); } if (!g_file_get_contents(options.currdir, ((gchar **)(&frame->data)), ((gsize *)(&frame->length)), NULL)) { fprintf(stderr, "g_file_get_contents failed on %s\n", options.currdir); return; } mime_types = gdk_pixbuf_format_get_mime_types(pformat); if (mime_types[0] != NULL) { if (frame->field_name != NULL) { free(frame->field_name); } frame->field_name = strdup(mime_types[0]); g_strfreev(mime_types); } else { fprintf(stderr, "error: no mime type for image %s\n", options.currdir); g_strfreev(mime_types); return; } vbox = gtk_widget_get_parent(source->image); gtk_widget_destroy(source->image); source->image = make_image_from_binary(frame); gtk_widget_show(source->image); gtk_container_add(GTK_CONTAINER(vbox), source->image); snprintf(str, MAXLEN-1, _("MIME type: %s"), frame->field_name); gtk_label_set_text(GTK_LABEL(source->mime_label), str); /* update callback data for 'Save picture' */ save_pic_update(save_pic, fi, frame); fi_mark_changed(fi); } GtkWidget * fi_procframe_label_apic(fi_t * fi, meta_frame_t * frame) { metadata_t * meta = fi->meta; apic_source_t * source; char * pic_caption; char str[MAXLEN]; GtkWidget * label_frame; GtkWidget * vbox = gtk_vbox_new(FALSE, 0); GtkWidget * hbox; GtkWidget * label; GtkWidget * button; change_pic_t * change_pic; save_pic_t * save_pic = (save_pic_t *)malloc(sizeof(save_pic_t)); if (save_pic == NULL) return NULL; trashlist_add(fi->trash, save_pic); change_pic = (change_pic_t *)malloc(sizeof(change_pic_t)); if (change_pic == NULL) return NULL; trashlist_add(fi->trash, change_pic); change_pic->fi = fi; change_pic->frame = frame; change_pic->save_pic = save_pic; frame->source = calloc(1, sizeof(apic_source_t)); if (frame->source == NULL) return NULL; trashlist_add(fi->trash, frame->source); source = ((apic_source_t *)(frame->source)); meta_get_fieldname(META_FIELD_APIC, &pic_caption); snprintf(str, MAXLEN-1, "%s:", pic_caption); label_frame = gtk_frame_new(pic_caption); gtk_container_add(GTK_CONTAINER(label_frame), vbox); gtk_container_set_border_width(GTK_CONTAINER(vbox), 5); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 3); snprintf(str, MAXLEN-1, _("MIME type: %s"), frame->field_name); source->mime_label = gtk_label_new(str); gtk_box_pack_start(GTK_BOX(hbox), source->mime_label, FALSE, FALSE, 0); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 3); label = gtk_label_new(_("Picture type:")); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); if (meta->writable) { int i = 0; char * type_str; hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 3); source->type_combo = gtk_combo_box_new_text(); while (1) { type_str = meta_id3v2_apic_type_to_string(i); if (type_str == NULL) { break; } gtk_combo_box_append_text(GTK_COMBO_BOX(source->type_combo), type_str); ++i; } gtk_combo_box_set_active(GTK_COMBO_BOX(source->type_combo), frame->int_val); gtk_box_pack_start(GTK_BOX(hbox), source->type_combo, TRUE, TRUE, 0); } else { hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 3); snprintf(str, MAXLEN-1, "%s", meta_id3v2_apic_type_to_string(frame->int_val)); label = gtk_label_new(str); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); } hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 3); label = gtk_label_new(_("Description:")); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); if (meta->writable) { hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 3); source->descr_entry = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(source->descr_entry), frame->field_val); gtk_box_pack_start(GTK_BOX(hbox), source->descr_entry, TRUE, TRUE, 0); } else { hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 3); label = gtk_label_new((frame->field_val[0] == '\0') ? _("(no description)") : frame->field_val); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); } hbox = gtk_hbox_new(TRUE, 0); gtk_box_pack_end(GTK_BOX(vbox), hbox, FALSE, FALSE, 3); button = gui_stock_label_button(_("Change"), GTK_STOCK_OPEN); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 3); if (meta->writable) { g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(change_pic_button_pressed), (gpointer)change_pic); } else { gtk_widget_set_sensitive(button, FALSE); } save_pic->save_button = gui_stock_label_button(_("Save"), GTK_STOCK_SAVE); gtk_box_pack_start(GTK_BOX(hbox), save_pic->save_button, TRUE, TRUE, 3); g_signal_connect(G_OBJECT(save_pic->save_button), "clicked", G_CALLBACK(save_pic_button_pressed), (gpointer)save_pic); save_pic_update(save_pic, fi, frame); return label_frame; } GtkWidget * fi_procframe_label(fi_t * fi, meta_frame_t * frame) { if (frame->type == META_FIELD_APIC) { return fi_procframe_label_apic(fi, frame); } else { char str[MAXLEN]; GtkWidget * hbox = gtk_hbox_new(FALSE, 0); GtkWidget * label; snprintf(str, MAXLEN-1, "%s:", frame->field_name); label = gtk_label_new(str); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); return hbox; } } void fi_entry_changed_cb(GtkEntry * entry, gpointer data) { fi_t * fi = (fi_t *)data; fi_mark_changed(fi); } gint genre_cmp(gconstpointer a, gconstpointer b) { return strcmp(id3v1_genre_str_from_code(GPOINTER_TO_INT(a)), id3v1_genre_str_from_code(GPOINTER_TO_INT(b))); } void make_genre_combo(meta_frame_t * frame, GtkWidget ** widget, GtkWidget ** entry) { int i; GtkWidget * combo = gtk_combo_box_entry_new_text(); GSList * list = NULL; GSList * _list; for (i = 0; i < 256; i++) { char * genre = id3v1_genre_str_from_code(i); if (genre == NULL) { break; } list = g_slist_append(list, GINT_TO_POINTER(i)); } list = g_slist_sort(list, genre_cmp); _list = list; while (_list != NULL) { char * genre = id3v1_genre_str_from_code(GPOINTER_TO_INT(_list->data)); gtk_combo_box_append_text(GTK_COMBO_BOX(combo), genre); _list = g_slist_next(_list); } g_slist_free(list); gtk_combo_box_set_wrap_width(GTK_COMBO_BOX(combo), 4); *widget = combo; *entry = GTK_WIDGET(GTK_BIN(combo)->child); if (frame->field_val[0] == '\0') { /* set default genre if none present */ gtk_entry_set_text(GTK_ENTRY(*entry), id3v1_genre_str_from_code(0)); } else { gtk_entry_set_text(GTK_ENTRY(*entry), frame->field_val); } /* for ID3v1, only predefined genres can be selected, no editing allowed */ if (frame->tag == META_TAG_ID3v1) { GTK_WIDGET_UNSET_FLAGS(*entry, GTK_CAN_FOCUS); gtk_editable_set_editable(GTK_EDITABLE(*entry), FALSE); } } void make_apic_widget(meta_frame_t * frame, GtkWidget ** widget, GtkWidget ** entry) { GtkWidget * apic_frame = gtk_frame_new(NULL); GtkWidget * image = make_image_from_binary(frame); GtkWidget * vbox = gtk_vbox_new(FALSE, 0); gtk_frame_set_shadow_type(GTK_FRAME(apic_frame), GTK_SHADOW_NONE); gtk_container_add(GTK_CONTAINER(apic_frame), vbox); gtk_container_set_border_width(GTK_CONTAINER(vbox), 5); gtk_box_pack_start(GTK_BOX(vbox), image, TRUE, TRUE, 0); *widget = apic_frame; *entry = apic_frame; ((apic_source_t *)(frame->source))->image = image; } GtkWidget * fi_procframe_entry(fi_t * fi, meta_frame_t * frame) { metadata_t * meta = fi->meta; GtkWidget * widget = NULL; GtkWidget * entry = NULL; if (META_FIELD_BIN(frame->type)) { /* TODO create image/whatever widget, etc. */ if (frame->type == META_FIELD_APIC) { make_apic_widget(frame, &widget, &entry); } } else if (META_FIELD_INT(frame->type)) { char str[MAXLEN]; char * format = meta_get_field_renderfmt(frame->type); widget = entry = gtk_entry_new(); snprintf(str, MAXLEN-1, format, frame->int_val); gtk_entry_set_text(GTK_ENTRY(entry), str); } else if (META_FIELD_FLOAT(frame->type)) { char str[MAXLEN]; char * format = meta_get_field_renderfmt(frame->type); widget = entry = gtk_entry_new(); snprintf(str, MAXLEN-1, format, frame->float_val); gtk_entry_set_text(GTK_ENTRY(entry), str); } else { if (meta->writable && (frame->type == META_FIELD_GENRE)) { make_genre_combo(frame, &widget, &entry); } else { widget = entry = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(entry), frame->field_val); } } if ((META_FIELD_TEXT(frame->type)) || (META_FIELD_INT(frame->type)) || (META_FIELD_FLOAT(frame->type))) { if (!meta->writable) { GTK_WIDGET_UNSET_FLAGS(entry, GTK_CAN_FOCUS); gtk_editable_set_editable(GTK_EDITABLE(entry), FALSE); } else { g_signal_connect(G_OBJECT(widget), "changed", G_CALLBACK(fi_entry_changed_cb), (gpointer)fi); } gtk_widget_set_size_request(widget, VAL_WIDGET_WIDTH, -1); } return widget; } import_data_t * make_import_data_from_frame(fi_t * fi, meta_frame_t * frame, char * label) { import_data_t * data = import_data_new(); trashlist_add(fi->trash, data); data->fi = fi; data->frame = frame; switch (frame->type) { case META_FIELD_TITLE: data->dest_type = IMPORT_DEST_TITLE; strcpy(label, _("Import as Title")); break; case META_FIELD_ARTIST: data->dest_type = IMPORT_DEST_ARTIST; strcpy(label, _("Import as Artist")); break; case META_FIELD_ALBUM: data->dest_type = IMPORT_DEST_RECORD; strcpy(label, _("Import as Record")); break; case META_FIELD_DATE: data->dest_type = IMPORT_DEST_YEAR; strcpy(label, _("Import as Year")); break; case META_FIELD_TRACKNO: data->dest_type = IMPORT_DEST_NUMBER; strcpy(label, _("Import as Track No.")); break; case META_FIELD_RG_TRACK_GAIN: case META_FIELD_RG_ALBUM_GAIN: case META_FIELD_RVA2: data->dest_type = IMPORT_DEST_RVA; strcpy(label, _("Import as RVA")); break; default: data->dest_type = IMPORT_DEST_COMMENT; strcpy(label, _("Add to Comments")); break; } return data; } GtkWidget * fi_procframe_importbtn(fi_t * fi, meta_frame_t * frame) { char label[MAXLEN]; GtkWidget * button = gtk_button_new(); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(import_button_pressed), (gpointer)make_import_data_from_frame(fi, frame, label)); gtk_button_set_label(GTK_BUTTON(button), label); return button; } void fi_fill_tagcombo(GtkComboBox * combo, int addable_tags) { int i; int tag = 1; if (!GTK_IS_COMBO_BOX(combo)) return; for (i = 0; i < 100; i++) { gtk_combo_box_remove_text(combo, 0); } if (addable_tags == 0) { gtk_widget_set_sensitive(GTK_WIDGET(combo), FALSE); return; } gtk_widget_set_sensitive(GTK_WIDGET(combo), TRUE); while (tag <= META_TAG_MAX) { if (addable_tags & tag) { gtk_combo_box_append_text(combo, meta_get_tagname(tag)); } tag <<= 1; } gtk_combo_box_set_active(combo, 0); } gint fi_fill_combo_cmp(gconstpointer a, gconstpointer b) { int field1 = GPOINTER_TO_INT(a); int field2 = GPOINTER_TO_INT(b); char * str1; char * str2; if (!meta_get_fieldname(field1, &str1)) { fprintf(stderr, "fi_fill_combo_cmp: programmer error #1\n"); } if (!meta_get_fieldname(field2, &str2)) { fprintf(stderr, "fi_fill_combo_cmp: programmer error #2\n"); } return strcmp(str1, str2); } void fi_fill_combo_foreach(gpointer data, gpointer user_data) { int field = GPOINTER_TO_INT(data); char * str; GtkComboBox * combo = (GtkComboBox *)user_data; if (!meta_get_fieldname(field, &str)) { fprintf(stderr, "fi_fill_combo_foreach: programmer error\n"); } gtk_combo_box_append_text(combo, str); } void fi_fill_combo(GtkComboBox * combo, GSList * slist) { int i; GSList * sorted_list = g_slist_copy(slist); for (i = 0; i < 100; i++) { gtk_combo_box_remove_text(combo, 0); } sorted_list = g_slist_sort(sorted_list, fi_fill_combo_cmp); g_slist_foreach(sorted_list, fi_fill_combo_foreach, combo); g_slist_free(sorted_list); gtk_combo_box_set_active(combo, 0); } typedef struct { fi_t * fi; meta_frame_t * frame; GtkWidget * label; GtkWidget * entry; GtkWidget * importbtn; GtkWidget * delbtn; } fi_del_t; void fi_del_button_pressed(GtkWidget * widget, gpointer data) { fi_del_t * fi_del = (fi_del_t *)data; fi_t * fi = fi_del->fi; metadata_t * meta = fi_del->fi->meta; meta_frame_t * frame = fi_del->frame; if (frame->flags & META_FIELD_UNIQUE) { int page = lookup_page(fi, frame->tag); GtkWidget * combo = fi->pageidx[page].combo; GSList * slist = fi->pageidx[page].slist; slist = g_slist_append(slist, GINT_TO_POINTER(frame->type)); fi->pageidx[page].slist = slist; fi_fill_combo(GTK_COMBO_BOX(combo), slist); } metadata_remove_frame(meta, frame); meta_frame_free(frame); gtk_widget_destroy(fi_del->label); gtk_widget_destroy(fi_del->entry); if (fi_del->importbtn != NULL) { gtk_widget_destroy(fi_del->importbtn); } gtk_widget_destroy(fi_del->delbtn); fi_mark_changed(fi); } GtkWidget * fi_procframe_delbtn(fi_t * fi, meta_frame_t * frame, GtkWidget * label, GtkWidget * entry, GtkWidget * importbtn) { fi_del_t * fi_del; GtkWidget * button = gtk_button_new(); gtk_button_set_image(GTK_BUTTON(button), gtk_image_new_from_stock(GTK_STOCK_DELETE, GTK_ICON_SIZE_MENU)); if (frame->flags & META_FIELD_MANDATORY) { gtk_widget_set_sensitive(button, FALSE); return button; } fi_del = calloc(1, sizeof(fi_del_t)); fi_del->fi = fi; fi_del->frame = frame; fi_del->label = label; fi_del->entry = entry; fi_del->importbtn = importbtn; fi_del->delbtn = button; trashlist_add(fi->trash, fi_del); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(fi_del_button_pressed), (gpointer)fi_del); return button; } typedef struct { fi_t * fi; int tag; } fi_add_t; void fi_add_button_pressed(GtkWidget * widget, gpointer data) { fi_add_t * fi_add = (fi_add_t *)data; fi_t * fi = fi_add->fi; metadata_t * meta = fi_add->fi->meta; int page = lookup_page(fi, fi_add->tag); GtkWidget * combo = fi->pageidx[page].combo; GSList * slist = fi->pageidx[page].slist; meta_frame_t * frame = meta_frame_new(); int type; char * str; /* Create new frame */ char * combo_entry = gtk_combo_box_get_active_text(GTK_COMBO_BOX(combo)); if (combo_entry == NULL) { return; } type = meta_frame_type_from_name(combo_entry); g_free(combo_entry); frame->tag = fi_add->tag; frame->type = type; frame->flags = meta_get_default_flags(fi_add->tag, type); if (meta_get_fieldname(type, &str)) { frame->field_name = strdup(str); } else { fprintf(stderr, "fi_add_button_pressed: programmer error\n"); } if (options.metaedit_auto_clone) { metadata_clone_frame(meta, frame); } if (frame->field_val == NULL) { frame->field_val = strdup(""); } frame->next = NULL; metadata_add_frame(meta, frame); if (frame->flags & META_FIELD_UNIQUE) { slist = g_slist_remove(slist, GINT_TO_POINTER(frame->type)); fi->pageidx[page].slist = slist; fi_fill_combo(GTK_COMBO_BOX(combo), slist); } fi_procframe_ins(fi, frame); fi_mark_changed(fi); } GtkWidget * fi_procframe_addbtn(fi_t * fi, int tag) { fi_add_t * fi_add; GtkWidget * button = gui_stock_label_button(_("Add"), GTK_STOCK_ADD); fi_add = calloc(1, sizeof(fi_add_t)); fi_add->fi = fi; fi_add->tag = tag; trashlist_add(fi->trash, fi_add); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(fi_add_button_pressed), (gpointer)fi_add); return button; } void fi_addtag_button_pressed(GtkWidget * widget, gpointer data) { fi_t * fi = (fi_t *)data; metadata_t * meta = fi->meta; meta_frame_t * frame; int tag; char * combo_entry = gtk_combo_box_get_active_text(GTK_COMBO_BOX(fi->combo)); if (combo_entry == NULL) { return; } frame = meta_frame_new(); tag = frame->tag = meta_tag_from_name(combo_entry); g_free(combo_entry); metadata_add_mandatory_frames(meta, frame->tag); fi_procframe_add_tag_page(fi, frame); fi->addable_tags &= ~frame->tag; fi_fill_tagcombo(GTK_COMBO_BOX(fi->combo), fi->addable_tags); meta_frame_free(frame); /* display fields, if any */ frame = metadata_get_frame_by_tag(meta, tag, NULL); while (frame != NULL) { fi_procframe_ins(fi, frame); frame = metadata_get_frame_by_tag(meta, tag, frame); } fi_mark_changed(fi); } GtkWidget * fi_procframe_addtagbtn(fi_t * fi) { GtkWidget * button = gui_stock_label_button(_("Add"), GTK_STOCK_ADD); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(fi_addtag_button_pressed), (gpointer)fi); return button; } #ifdef HAVE_MOD_INFO void fi_procframe_ins_modinfo(fi_t * fi, meta_frame_t * frame) { int page = lookup_page(fi, frame->tag); GtkWidget * table = fi->pageidx[page].table; GtkWidget * vbox = gtk_vbox_new(FALSE, 0); module_info_fill_page(fi, frame, vbox); gtk_table_attach(GTK_TABLE(table), vbox, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); gtk_widget_show_all(fi->nb); } #endif /* HAVE_MOD_INFO */ void fi_procframe_ins(fi_t * fi, meta_frame_t * frame) { metadata_t * meta = fi->meta; int page = lookup_page(fi, frame->tag); GtkWidget * table = fi->pageidx[page].table; int n_rows = fi->pageidx[page].n_rows; int n_cols = fi->pageidx[page].n_cols; int col = 0; GtkWidget * label = NULL; GtkWidget * entry = NULL; GtkWidget * importbtn = NULL; GtkWidget * delbtn = NULL; if (frame->type == META_FIELD_HIDDEN) { return; } #ifdef HAVE_MOD_INFO if (frame->type == META_FIELD_MODINFO) { fi_procframe_ins_modinfo(fi, frame); return; } #endif /* HAVE_MOD_INFO */ if (frame->type == META_FIELD_APIC) { /* only display first APIC found */ meta_frame_t * first_apic = metadata_get_frame_by_type(fi->meta, META_FIELD_APIC, NULL); if (frame == first_apic) { display_cover_from_binary(fi->cover_image_area, fi->event_box, fi->cover_align, 48, 48, frame->data, frame->length, FALSE, TRUE); } } ++n_rows; fi->pageidx[page].n_rows = n_rows; gtk_table_resize(GTK_TABLE(table), n_rows, n_cols); /* Field label */ label = fi_procframe_label(fi, frame); gtk_table_attach(GTK_TABLE(table), label, col, col+1, n_rows-1, n_rows, GTK_FILL, GTK_FILL, 5, 3); ++col; /* Field entry */ entry = fi_procframe_entry(fi, frame); gtk_table_attach(GTK_TABLE(table), entry, col, col+1, n_rows-1, n_rows, GTK_EXPAND | GTK_FILL, GTK_FILL, 5, 3); if (frame->type != META_FIELD_APIC) { frame->source = entry; } ++col; /* Import button */ if (fi->is_called_from_browser) { importbtn = fi_procframe_importbtn(fi, frame); gtk_table_attach(GTK_TABLE(table), importbtn, col, col+1, n_rows-1, n_rows, GTK_FILL, GTK_FILL, 5, 3); ++col; } /* Delete button */ if (meta->writable) { delbtn = fi_procframe_delbtn(fi, frame, label, entry, importbtn); gtk_table_attach(GTK_TABLE(table), delbtn, col, col+1, n_rows-1, n_rows, GTK_FILL, GTK_FILL, 5, 3); ++col; } if (meta->writable && (frame->flags & META_FIELD_UNIQUE)) { GtkWidget * combo = fi->pageidx[page].combo; GSList * slist = fi->pageidx[page].slist; slist = g_slist_remove(slist, GINT_TO_POINTER(frame->type)); fi->pageidx[page].slist = slist; fi_fill_combo(GTK_COMBO_BOX(combo), slist); } gtk_widget_show_all(fi->nb); } typedef struct { fi_t * fi; int tag; } fi_deltag_t; void fi_deltag_button_pressed(GtkWidget * widget, gpointer data) { fi_deltag_t * fi_deltag = (fi_deltag_t *)data; fi_t * fi = fi_deltag->fi; int tag = fi_deltag->tag; metadata_t * meta = fi->meta; meta_frame_t * frame; int i; /* Remove all frames with frame->tag == tag */ frame = meta->root; while (frame != NULL) { if (frame->tag == tag) { meta_frame_t * f = frame->next; metadata_remove_frame(meta, frame); meta_frame_free(frame); frame = f; } else { frame = frame->next; } } /* Remove notebook page and update fi->pageidx */ for (i = 0; i < FI_MAXPAGES; i++) { if (fi->pageidx[i].tag == tag) { int k; for (k = i; k < FI_MAXPAGES-1; k++) { fi->pageidx[k] = fi->pageidx[k+1]; } fi->pageidx[FI_MAXPAGES-1].tag = -1; gtk_notebook_remove_page(GTK_NOTEBOOK(fi->nb), i); --fi->n_pages; break; } } fi->addable_tags |= tag; fi_fill_tagcombo(GTK_COMBO_BOX(fi->combo), fi->addable_tags); fi_mark_changed(fi); } GtkWidget * fi_procframe_deltagbtn(fi_t * fi, int tag) { fi_deltag_t * fi_deltag; GtkWidget * button = gtk_button_new(); gtk_button_set_image(GTK_BUTTON(button), gtk_image_new_from_stock(GTK_STOCK_DELETE, GTK_ICON_SIZE_MENU)); fi_deltag = calloc(1, sizeof(fi_deltag_t)); fi_deltag->fi = fi; fi_deltag->tag = tag; trashlist_add(fi->trash, fi_deltag); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(fi_deltag_button_pressed), (gpointer)fi_deltag); return button; } void fi_procframe_add_tag_page(fi_t * fi, meta_frame_t * frame) { metadata_t * meta = fi->meta; GtkWidget * vbox = gtk_vbox_new(FALSE, 4); GtkWidget * vbox_padding = gtk_vbox_new(FALSE, 0); GtkWidget * scrwin = gtk_scrolled_window_new(NULL, NULL); GtkWidget * table = gtk_table_new(0, fi_tabwidth(fi, meta), FALSE); GtkWidget * label = gtk_label_new(meta_get_tagname(frame->tag)); GtkWidget * hbox = gtk_hbox_new(FALSE, 0); GtkWidget * combo = gtk_combo_box_new_text(); GtkWidget * addbtn, * delbtn; GSList * slist = meta_get_possible_fields(frame->tag); gtk_box_pack_start(GTK_BOX(vbox_padding), table, TRUE, TRUE, 7); gtk_box_pack_start(GTK_BOX(vbox), scrwin, TRUE, TRUE, 0); gtk_widget_set_size_request(scrwin, -1, 275); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrwin), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrwin), GTK_SHADOW_NONE); gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrwin), vbox_padding); gtk_notebook_append_page(GTK_NOTEBOOK(fi->nb), vbox, label); fi->n_pages++; fi->pageidx[fi->n_pages-1].tag = frame->tag; fi->pageidx[fi->n_pages-1].table = table; fi->pageidx[fi->n_pages-1].combo = combo; fi->pageidx[fi->n_pages-1].slist = slist; fi->pageidx[fi->n_pages-1].n_rows = 0; fi->pageidx[fi->n_pages-1].n_cols = fi_tabwidth(fi, meta); if (meta->writable) { addbtn = fi_procframe_addbtn(fi, frame->tag); gtk_box_pack_start(GTK_BOX(hbox), addbtn, FALSE, FALSE, 5); label = gtk_label_new(_("field:")); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5); fi_fill_combo(GTK_COMBO_BOX(combo), slist); gtk_box_pack_start(GTK_BOX(hbox), combo, FALSE, FALSE, 5); delbtn = fi_procframe_deltagbtn(fi, frame->tag); gtk_box_pack_end(GTK_BOX(hbox), delbtn, FALSE, FALSE, 5); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5); fi->addable_tags &= ~frame->tag; fi_fill_tagcombo(GTK_COMBO_BOX(fi->combo), fi->addable_tags); } gtk_widget_show_all(fi->nb); } void fi_procframe(fi_t * fi, meta_frame_t * frame) { int page = lookup_page(fi, frame->tag); if (page == -1) { fi_procframe_add_tag_page(fi, frame); } fi_procframe_ins(fi, frame); } typedef struct { metadata_t * meta; void * data; } fi_procmeta_wait_data_t; void fi_procmeta(metadata_t * meta, void * data); gboolean fi_procmeta_wait(gpointer cb_data) { fi_procmeta_wait_data_t * wd = (fi_procmeta_wait_data_t *)cb_data; fi_procmeta(wd->meta, wd->data); free(wd); return FALSE; } void fi_procmeta(metadata_t * meta, void * data) { fi_t * fi = (fi_t *)data; meta_frame_t * frame; int i; if (fi->bail_out) { /* this condition signals that file_decoder_open in show_file_info has failed */ fi_delete(fi); return; } if ((fi->nb == NULL) || !GTK_IS_NOTEBOOK(fi->nb)) { fi_procmeta_wait_data_t * fi_procmeta_wait_data = calloc(1, sizeof(fi_procmeta_wait_data_t)); fi_procmeta_wait_data->meta = meta; fi_procmeta_wait_data->data = data; aqualung_timeout_add(100, fi_procmeta_wait, (gpointer)fi_procmeta_wait_data); return; } if (fi->meta == meta) { return; } /* remove possible previous metadata pages from notebook */ for (i = 0; i < FI_MAXPAGES; i++) { if (fi->pageidx[i].tag != -1) { gtk_notebook_remove_page(GTK_NOTEBOOK(fi->nb), i); fi->pageidx[i].tag = -1; } } if (fi->meta != NULL) { metadata_free(fi->meta); } fi->meta = meta; fi->addable_tags = meta->valid_tags; frame = meta->root; while (frame != NULL) { fi_procframe(fi, frame); frame = frame->next; } if (fi->meta->writable && (fi->save_button == NULL)) { fi->save_button = gtk_button_new_from_stock(GTK_STOCK_SAVE); g_signal_connect(fi->save_button, "clicked", G_CALLBACK(fi_save), (gpointer)fi); gtk_table_attach(GTK_TABLE(fi->button_table), fi->save_button, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 5, 3); gtk_widget_show_all(fi->info_window); } if (fi->meta->writable && (fi->combo == NULL)) { GtkWidget * addbtn, * label; addbtn = fi_procframe_addtagbtn(fi); gtk_box_pack_start(GTK_BOX(fi->hbox), addbtn, FALSE, FALSE, 5); label = gtk_label_new(_("tag:")); gtk_box_pack_start(GTK_BOX(fi->hbox), label, FALSE, FALSE, 5); fi->combo = gtk_combo_box_new_text(); fi_fill_tagcombo(GTK_COMBO_BOX(fi->combo), fi->addable_tags); gtk_box_pack_start(GTK_BOX(fi->hbox), fi->combo, FALSE, FALSE, 5); gtk_widget_show_all(fi->info_window); } fi_set_page(fi); } gboolean fi_cover_press_button_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { fi_t * fi = (fi_t *)data; if (event->type == GDK_BUTTON_PRESS && event->button == 1) { meta_frame_t * frame; frame = metadata_get_frame_by_type(fi->meta, META_FIELD_APIC, NULL); if (frame != NULL) { display_zoomed_cover_from_binary(fi->info_window, fi->event_box, frame->data, frame->length); } else { display_zoomed_cover(fi->info_window, fi->event_box, (gchar *)fi->filename); } } return TRUE; } void show_file_info(char * name, char * file, int is_called_from_browser, GtkTreeModel * model, GtkTreeIter track_iter, gboolean cover_flag) { char str[MAXLEN]; gchar * file_display; GtkWidget * vbox; GtkWidget * hbox_t; GtkWidget * table; GtkWidget * hbox_name; GtkWidget * label_name; GtkWidget * entry_name; GtkWidget * hbox_path; GtkWidget * label_path; GtkWidget * entry_path; GtkWidget * dismiss_btn; GtkWidget * vbox_file; GtkWidget * label_file; GtkWidget * table_file; GtkWidget * hbox; GtkWidget * label; GtkWidget * entry; decoder_t * dec = NULL; int is_cdda = 0; fileinfo_t fileinfo; fi_t * fi = fi_new(); if (fi == NULL) { return; } #ifdef HAVE_CDDA if ((strlen(file) > 4) && (file[0] == 'C') && (file[1] == 'D') && (file[2] == 'D') && (file[3] == 'A')) { char device_path[CDDA_MAXLEN]; long hash; int track; cdda_drive_t * drive; if (sscanf(file, "CDDA %s %lX %u", device_path, &hash, &track) < 3) { return; } drive = cdda_get_drive_by_device_path(device_path); if ((drive == NULL) || (drive->disc.hash == 0L)) { return; } is_cdda = 1; fileinfo.format_str = _("Audio CD"); fileinfo.sample_rate = 44100; fileinfo.is_mono = 0; fileinfo.format_flags = 0; fileinfo.bps = 2*16*44100; fileinfo.total_samples = (drive->disc.toc[track] - drive->disc.toc[track-1]) * 588; } #endif /* HAVE_CDDA */ if (!is_cdda) { fi->fdec = file_decoder_new(); if (fi->fdec == NULL) { fi_delete(fi); return; } file_decoder_set_meta_cb(fi->fdec, fi_procmeta, fi); if (file_decoder_open(fi->fdec, file) != 0) { fi->bail_out = 1; return; } file_decoder_send_metadata(fi->fdec); dec = (decoder_t *)fi->fdec->pdec; fileinfo.format_str = dec->format_str; fileinfo.sample_rate = fi->fdec->fileinfo.sample_rate; fileinfo.is_mono = fi->fdec->fileinfo.is_mono; fileinfo.format_flags = fi->fdec->fileinfo.format_flags; fileinfo.bps = fi->fdec->fileinfo.bps; fileinfo.total_samples = fi->fdec->fileinfo.total_samples; } fi->is_called_from_browser = is_called_from_browser; fi->model = model; fi->track_iter = track_iter; fi->filename = strdup(file); fi->trash = trashlist_new(); fi->info_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); register_toplevel_window(fi->info_window, TOP_WIN_SKIN | TOP_WIN_TRAY); gtk_window_set_title(GTK_WINDOW(fi->info_window), _("File info")); gtk_window_set_modal(GTK_WINDOW(fi->info_window), TRUE); gtk_window_set_transient_for(GTK_WINDOW(fi->info_window), GTK_WINDOW(main_window)); gtk_window_set_position(GTK_WINDOW(fi->info_window), GTK_WIN_POS_CENTER); gtk_window_set_resizable(GTK_WINDOW(fi->info_window), TRUE); g_signal_connect(G_OBJECT(fi->info_window), "delete_event", G_CALLBACK(info_window_close), (gpointer)fi); g_signal_connect(G_OBJECT(fi->info_window), "key_press_event", G_CALLBACK(info_window_key_pressed), (gpointer)fi); gtk_container_set_border_width(GTK_CONTAINER(fi->info_window), 5); vbox = gtk_vbox_new(FALSE, 0); gtk_container_add(GTK_CONTAINER(fi->info_window), vbox); hbox_t = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox), hbox_t, FALSE, FALSE, 5); table = gtk_table_new(2, 2, FALSE); gtk_box_pack_start(GTK_BOX(hbox_t), table, TRUE, TRUE, 4); hbox_name = gtk_hbox_new(FALSE, 0); label_name = gtk_label_new(_("Track:")); gtk_box_pack_start(GTK_BOX(hbox_name), label_name, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(table), hbox_name, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 5, 2); entry_name = gtk_entry_new(); GTK_WIDGET_UNSET_FLAGS(entry_name, GTK_CAN_FOCUS); gtk_entry_set_text(GTK_ENTRY(entry_name), name); gtk_editable_set_editable(GTK_EDITABLE(entry_name), FALSE); gtk_table_attach(GTK_TABLE(table), entry_name, 1, 2, 0, 1, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), GTK_FILL, 5, 2); hbox_path = gtk_hbox_new(FALSE, 0); label_path = gtk_label_new(_("File:")); gtk_box_pack_start(GTK_BOX(hbox_path), label_path, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(table), hbox_path, 0, 1, 1, 2, GTK_FILL, GTK_FILL, 5, 2); file_display = g_filename_display_name(file); entry_path = gtk_entry_new(); GTK_WIDGET_UNSET_FLAGS(entry_path, GTK_CAN_FOCUS); gtk_entry_set_text(GTK_ENTRY(entry_path), file_display); g_free(file_display); gtk_editable_set_editable(GTK_EDITABLE(entry_path), FALSE); gtk_table_attach(GTK_TABLE(table), entry_path, 1, 2, 1, 2, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), GTK_FILL, 5, 2); fi->cover_align = gtk_alignment_new(0.5f, 0.5f, 0.0f, 0.0f); gtk_box_pack_start(GTK_BOX(hbox_t), fi->cover_align, FALSE, FALSE, 0); fi->cover_image_area = gtk_image_new(); fi->event_box = gtk_event_box_new (); gtk_container_add(GTK_CONTAINER(fi->cover_align), fi->event_box); gtk_container_add (GTK_CONTAINER (fi->event_box), fi->cover_image_area); g_signal_connect(G_OBJECT(fi->event_box), "button_press_event", G_CALLBACK(fi_cover_press_button_cb), (gpointer)fi); if (options.show_cover_for_ms_tracks_only == TRUE) { if (cover_flag == TRUE) { display_cover(fi->cover_image_area, fi->event_box, fi->cover_align, 48, 48, file, FALSE, TRUE); } else { hide_cover_thumbnail(); } } else { display_cover(fi->cover_image_area, fi->event_box, fi->cover_align, 48, 48, file, FALSE, TRUE); } fi->hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_end(GTK_BOX(vbox), fi->hbox, FALSE, FALSE, 5); fi->nb = gtk_notebook_new(); gtk_box_pack_start(GTK_BOX(vbox), fi->nb, TRUE, TRUE, 5); /* Audio data notebook page */ vbox_file = gtk_vbox_new(FALSE, 4); table_file = gtk_table_new(6, 2, FALSE); gtk_box_pack_start(GTK_BOX(vbox_file), table_file, TRUE, TRUE, 10); label_file = gtk_label_new(_("Audio data")); fi->pageidx[0].tag = -1; gtk_notebook_append_page(GTK_NOTEBOOK(fi->nb), vbox_file, label_file); hbox = gtk_hbox_new(FALSE, 0); label = gtk_label_new(_("Format:")); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(table_file), hbox, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 5, 3); entry = gtk_entry_new(); gtk_widget_set_size_request(entry, 350, -1); GTK_WIDGET_UNSET_FLAGS(entry, GTK_CAN_FOCUS); gtk_entry_set_text(GTK_ENTRY(entry), fileinfo.format_str); gtk_editable_set_editable(GTK_EDITABLE(entry), FALSE); gtk_table_attach(GTK_TABLE(table_file), entry, 1, 2, 0, 1, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), GTK_FILL, 5, 3); hbox = gtk_hbox_new(FALSE, 0); label = gtk_label_new(_("Length:")); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(table_file), hbox, 0, 1, 1, 2, GTK_FILL, GTK_FILL, 5, 3); entry = gtk_entry_new(); GTK_WIDGET_UNSET_FLAGS(entry, GTK_CAN_FOCUS); if (fileinfo.total_samples == 0) { strcpy(str, "N/A"); } else { sample2time(fileinfo.sample_rate, fileinfo.total_samples, str, 0); } gtk_entry_set_text(GTK_ENTRY(entry), str); gtk_editable_set_editable(GTK_EDITABLE(entry), FALSE); gtk_table_attach(GTK_TABLE(table_file), entry, 1, 2, 1, 2, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), GTK_FILL, 5, 3); hbox = gtk_hbox_new(FALSE, 0); label = gtk_label_new(_("Samplerate:")); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(table_file), hbox, 0, 1, 2, 3, GTK_FILL, GTK_FILL, 5, 3); entry = gtk_entry_new(); GTK_WIDGET_UNSET_FLAGS(entry, GTK_CAN_FOCUS); sprintf(str, _("%ld Hz"), fileinfo.sample_rate); gtk_entry_set_text(GTK_ENTRY(entry), str); gtk_editable_set_editable(GTK_EDITABLE(entry), FALSE); gtk_table_attach(GTK_TABLE(table_file), entry, 1, 2, 2, 3, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), GTK_FILL, 5, 3); hbox = gtk_hbox_new(FALSE, 0); label = gtk_label_new(_("Channel count:")); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(table_file), hbox, 0, 1, 3, 4, GTK_FILL, GTK_FILL, 5, 3); entry = gtk_entry_new(); GTK_WIDGET_UNSET_FLAGS(entry, GTK_CAN_FOCUS); if (fileinfo.is_mono) strcpy(str, _("MONO")); else strcpy(str, _("STEREO")); gtk_entry_set_text(GTK_ENTRY(entry), str); gtk_editable_set_editable(GTK_EDITABLE(entry), FALSE); gtk_table_attach(GTK_TABLE(table_file), entry, 1, 2, 3, 4, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), GTK_FILL, 5, 3); hbox = gtk_hbox_new(FALSE, 0); label = gtk_label_new(_("Bandwidth:")); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(table_file), hbox, 0, 1, 4, 5, GTK_FILL, GTK_FILL, 5, 3); entry = gtk_entry_new(); GTK_WIDGET_UNSET_FLAGS(entry, GTK_CAN_FOCUS); if (fileinfo.bps == 0) { strcpy(str, "N/A kbit/s"); } else { format_bps_label(fileinfo.bps, fileinfo.format_flags, str); } gtk_entry_set_text(GTK_ENTRY(entry), str); gtk_editable_set_editable(GTK_EDITABLE(entry), FALSE); gtk_table_attach(GTK_TABLE(table_file), entry, 1, 2, 4, 5, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), GTK_FILL, 5, 3); hbox = gtk_hbox_new(FALSE, 0); label = gtk_label_new(_("Total samples:")); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(table_file), hbox, 0, 1, 5, 6, GTK_FILL, GTK_FILL, 5, 3); entry = gtk_entry_new(); GTK_WIDGET_UNSET_FLAGS(entry, GTK_CAN_FOCUS); if (fileinfo.total_samples == 0) { strcpy(str, "N/A"); } else { sprintf(str, "%lld", fileinfo.total_samples); } gtk_entry_set_text(GTK_ENTRY(entry), str); gtk_editable_set_editable(GTK_EDITABLE(entry), FALSE); gtk_table_attach(GTK_TABLE(table_file), entry, 1, 2, 5, 6, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), GTK_FILL, 5, 3); #ifdef HAVE_WAVPACK if (!is_cdda && fi->fdec->file_lib == WAVPACK_LIB) { wavpack_pdata_t * pd = (wavpack_pdata_t *)dec->pdata; int mode = WavpackGetMode(pd->wpc); hbox = gtk_hbox_new(FALSE, 0); label = gtk_label_new(_("Mode:")); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(table_file), hbox, 0, 1, 7, 8, GTK_FILL, GTK_FILL, 5, 3); entry = gtk_entry_new(); GTK_WIDGET_UNSET_FLAGS(entry, GTK_CAN_FOCUS); if ((mode & MODE_LOSSLESS) && (mode & MODE_WVC)) { strncpy(str, "Hybrid Lossless", MAXLEN-1); } else if (mode & MODE_LOSSLESS) { strncpy(str, "Lossless", MAXLEN-1); } else { strncpy(str, "Hybrid Lossy", MAXLEN-1); } cut_trailing_whitespace(str); gtk_entry_set_text(GTK_ENTRY(entry), str); gtk_editable_set_editable(GTK_EDITABLE(entry), FALSE); gtk_table_attach(GTK_TABLE(table_file), entry, 1, 2, 7, 8, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), GTK_FILL, 5, 3); } #endif /* HAVE_WAVPACK */ /* end of notebook stuff */ gtk_widget_grab_focus(fi->nb); fi->button_table = gtk_table_new(1, 2, TRUE); gtk_box_pack_end(GTK_BOX(fi->hbox), fi->button_table, FALSE, TRUE, 3); dismiss_btn = gtk_button_new_from_stock (GTK_STOCK_CLOSE); g_signal_connect(dismiss_btn, "clicked", G_CALLBACK(dismiss), (gpointer)fi); gtk_table_attach(GTK_TABLE(fi->button_table), dismiss_btn, 1, 2, 0, 1, GTK_FILL, GTK_FILL, 5, 3); gtk_widget_show_all(fi->info_window); fi_set_page(fi); /* fi_t object is freed in info_window destroy handlers */ } #ifdef HAVE_MOD_INFO /* * type = 0 for sample list * type != 0 for instrument list */ void show_list(fi_t * fi, gint type) { GtkTreeIter iter; gint i, len; gchar temp[MAXLEN], number[MAXLEN]; decoder_t * md_dec; mod_pdata_t * md_pd; md_dec = (decoder_t *)(fi->fdec->pdec); md_pd = (mod_pdata_t *)md_dec->pdata; if (type) { len = ModPlug_NumInstruments(md_pd->mpf); } else { len = ModPlug_NumSamples(md_pd->mpf); } if (len) { gtk_list_store_clear(fi->smp_instr_list_store); for(i = 0; i < len; i++) { memset(temp, 0, MAXLEN-1); if (type) { ModPlug_InstrumentName(md_pd->mpf, i, temp); } else { ModPlug_SampleName(md_pd->mpf, i, temp); } sprintf(number, "%2d", i); gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(fi->smp_instr_list_store), &iter, NULL, i); gtk_list_store_append(fi->smp_instr_list_store, &iter); gtk_list_store_set(fi->smp_instr_list_store, &iter, 0, number, 1, temp, -1); } } } void set_first_row(fi_t * fi) { GtkTreeIter iter; GtkTreePath * visible_path; gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(fi->smp_instr_list_store), &iter, NULL, 0); visible_path = gtk_tree_model_get_path(GTK_TREE_MODEL(fi->smp_instr_list_store), &iter); gtk_tree_view_set_cursor(GTK_TREE_VIEW(fi->smp_instr_list), visible_path, NULL, TRUE); gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(fi->smp_instr_list), visible_path, NULL, TRUE, 1.0, 0.0); gtk_widget_grab_focus(GTK_WIDGET(fi->smp_instr_list)); } void radio_buttons_cb(GtkToggleButton * toggle_button, gpointer data) { fi_t * fi = (fi_t *)data; if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toggle_button))) { show_list(fi, 0); } else { show_list(fi, 1); } set_first_row(fi); } void module_info_fill_page(fi_t * fi, meta_frame_t * frame, GtkWidget * vbox) { mod_info * mdi = (mod_info *)frame->data; gchar *a_type[] = { "None", "MOD", "S3M", "XM", "MED", "MTM", "IT", "669", "ULT", "STM", "FAR", "WAV", "AMF", "AMS", "DSM", "MDL", "OKT", "MID", "DMF", "PTM", "DBM", "MT2", "AMF0", "PSM", "J2B", "UMX" }; gint i, n; gchar temp[MAXLEN]; GtkWidget *table; GtkWidget *label; GtkWidget *mod_type_label; GtkWidget *mod_channels_label; GtkWidget *mod_patterns_label; GtkWidget *mod_samples_label; GtkWidget *mod_instruments_label; GtkWidget *vseparator; GtkWidget *hbox2; GtkWidget *vbox2; GtkWidget *vbox3; GtkWidget *samples_radiobutton = NULL; GtkWidget *instruments_radiobutton = NULL; GtkWidget *scrolledwindow; GtkCellRenderer *renderer; GtkTreeViewColumn *column; hbox2 = gtk_hbox_new (FALSE, 0); gtk_widget_show (hbox2); gtk_box_pack_start (GTK_BOX (vbox), hbox2, TRUE, TRUE, 0); vbox2 = gtk_vbox_new (FALSE, 0); gtk_widget_show (vbox2); gtk_box_pack_start (GTK_BOX (hbox2), vbox2, FALSE, FALSE, 0); if (mdi->instruments) { table = gtk_table_new (5, 2, FALSE); gtk_widget_show (table); gtk_box_pack_start (GTK_BOX (vbox2), table, FALSE, FALSE, 0); gtk_container_set_border_width (GTK_CONTAINER (table), 8); gtk_table_set_row_spacings (GTK_TABLE (table), 6); gtk_table_set_col_spacings (GTK_TABLE (table), 4); label = gtk_label_new (_("Type:")); gtk_widget_show (label); gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5); mod_type_label = gtk_label_new (""); gtk_widget_show (mod_type_label); gtk_table_attach (GTK_TABLE (table), mod_type_label, 1, 2, 0, 1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); label = gtk_label_new (_("Channels:")); gtk_widget_show (label); gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5); mod_channels_label = gtk_label_new (""); gtk_widget_show (mod_channels_label); gtk_table_attach (GTK_TABLE (table), mod_channels_label, 1, 2, 1, 2, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); label = gtk_label_new (_("Patterns:")); gtk_widget_show (label); gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5); mod_patterns_label = gtk_label_new (""); gtk_widget_show (mod_patterns_label); gtk_table_attach (GTK_TABLE (table), mod_patterns_label, 1, 2, 2, 3, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); label = gtk_label_new (_("Samples:")); gtk_widget_show (label); gtk_table_attach (GTK_TABLE (table), label, 0, 1, 3, 4, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5); mod_samples_label = gtk_label_new (""); gtk_widget_show (mod_samples_label); gtk_table_attach (GTK_TABLE (table), mod_samples_label, 1, 2, 3, 4, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); label = gtk_label_new (_("Instruments:")); gtk_widget_show (label); gtk_table_attach (GTK_TABLE (table), label, 0, 1, 4, 5, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5); mod_instruments_label = gtk_label_new (""); gtk_widget_show (mod_instruments_label); gtk_table_attach (GTK_TABLE (table), mod_instruments_label, 1, 2, 4, 5, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); sprintf(temp, "%d", mdi->instruments); gtk_label_set_text (GTK_LABEL(mod_instruments_label), temp); table = gtk_table_new (2, 1, FALSE); gtk_widget_show (table); gtk_box_pack_end (GTK_BOX (vbox2), table, FALSE, FALSE, 0); gtk_container_set_border_width (GTK_CONTAINER (table), 8); gtk_table_set_row_spacings (GTK_TABLE (table), 4); samples_radiobutton = gtk_radio_button_new_with_mnemonic (NULL, _("Samples")); gtk_widget_show (samples_radiobutton); gtk_table_attach (GTK_TABLE (table), samples_radiobutton, 0, 1, 0, 1, (GtkAttachOptions) (GTK_FILL | GTK_EXPAND), (GtkAttachOptions) (0), 0, 0); g_signal_connect(G_OBJECT(samples_radiobutton), "toggled", G_CALLBACK(radio_buttons_cb), (gpointer)fi); instruments_radiobutton = gtk_radio_button_new_with_mnemonic_from_widget (GTK_RADIO_BUTTON(samples_radiobutton), _("Instruments")); gtk_widget_show (instruments_radiobutton); gtk_table_attach (GTK_TABLE (table), instruments_radiobutton, 0, 1, 1, 2, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); } else { table = gtk_table_new (4, 2, FALSE); gtk_widget_show (table); gtk_box_pack_start (GTK_BOX (vbox2), table, FALSE, FALSE, 0); gtk_container_set_border_width (GTK_CONTAINER (table), 8); gtk_table_set_row_spacings (GTK_TABLE (table), 4); gtk_table_set_col_spacings (GTK_TABLE (table), 4); label = gtk_label_new (_("Type:")); gtk_widget_show (label); gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5); mod_type_label = gtk_label_new (""); gtk_widget_show (mod_type_label); gtk_table_attach (GTK_TABLE (table), mod_type_label, 1, 2, 0, 1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); label = gtk_label_new (_("Channels:")); gtk_widget_show (label); gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5); mod_channels_label = gtk_label_new (""); gtk_widget_show (mod_channels_label); gtk_table_attach (GTK_TABLE (table), mod_channels_label, 1, 2, 1, 2, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); label = gtk_label_new (_("Patterns:")); gtk_widget_show (label); gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5); mod_patterns_label = gtk_label_new (""); gtk_widget_show (mod_patterns_label); gtk_table_attach (GTK_TABLE (table), mod_patterns_label, 1, 2, 2, 3, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); label = gtk_label_new (_("Samples:")); gtk_widget_show (label); gtk_table_attach (GTK_TABLE (table), label, 0, 1, 3, 4, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5); mod_samples_label = gtk_label_new (""); gtk_widget_show (mod_samples_label); gtk_table_attach (GTK_TABLE (table), mod_samples_label, 1, 2, 3, 4, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); } n = mdi->type; i = 0; while (n > 0) { /* calculate module type index */ n >>= 1; i++; } gtk_label_set_text (GTK_LABEL(mod_type_label), a_type[i]); sprintf(temp, "%d", mdi->channels); gtk_label_set_text (GTK_LABEL(mod_channels_label), temp); sprintf(temp, "%d", mdi->patterns); gtk_label_set_text (GTK_LABEL(mod_patterns_label), temp); sprintf(temp, "%d", mdi->samples); gtk_label_set_text (GTK_LABEL(mod_samples_label), temp); vseparator = gtk_vseparator_new (); gtk_widget_show (vseparator); gtk_box_pack_start (GTK_BOX (hbox2), vseparator, FALSE, FALSE, 4); vbox3 = gtk_vbox_new (FALSE, 0); gtk_widget_show (vbox3); gtk_box_pack_start (GTK_BOX (hbox2), vbox3, TRUE, TRUE, 0); scrolledwindow = gtk_scrolled_window_new (NULL, NULL); gtk_container_set_border_width (GTK_CONTAINER (scrolledwindow), 4); gtk_widget_show (scrolledwindow); gtk_widget_set_size_request (scrolledwindow, -1, 220); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_box_pack_end (GTK_BOX (vbox3), scrolledwindow, TRUE, TRUE, 0); gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow), GTK_SHADOW_IN); fi->smp_instr_list_store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING); fi->smp_instr_list = gtk_tree_view_new_with_model(GTK_TREE_MODEL(fi->smp_instr_list_store)); gtk_widget_set_name(fi->smp_instr_list, "samples_instruments_list"); gtk_widget_show (fi->smp_instr_list); renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes(_("No."), renderer, "text", 0, NULL); gtk_tree_view_column_set_sizing(GTK_TREE_VIEW_COLUMN(column), GTK_TREE_VIEW_COLUMN_FIXED); gtk_tree_view_column_set_spacing(GTK_TREE_VIEW_COLUMN(column), 3); gtk_tree_view_column_set_resizable(GTK_TREE_VIEW_COLUMN(column), FALSE); gtk_tree_view_column_set_fixed_width(GTK_TREE_VIEW_COLUMN(column), 40); gtk_tree_view_append_column(GTK_TREE_VIEW(fi->smp_instr_list), column); column = gtk_tree_view_column_new_with_attributes(_("Name"), renderer, "text", 1, NULL); gtk_tree_view_column_set_sizing(GTK_TREE_VIEW_COLUMN(column), GTK_TREE_VIEW_COLUMN_FIXED); gtk_tree_view_append_column(GTK_TREE_VIEW(fi->smp_instr_list), column); gtk_tree_view_column_set_spacing(GTK_TREE_VIEW_COLUMN(column), 3); gtk_tree_view_column_set_resizable(GTK_TREE_VIEW_COLUMN(column), FALSE); gtk_container_add (GTK_CONTAINER (scrolledwindow), fi->smp_instr_list); if (mdi->instruments && mdi->type == 0x4) { /* if XM module go to instrument page */ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(instruments_radiobutton), TRUE); } else { show_list(fi, 0); set_first_row(fi); } } #endif /* HAVE_MOD_INFO */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/gui_main.h0000644000175000001440000000372211316204256013646 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: gui_main.h 1031 2008-10-14 19:02:47Z peterszilagyi $ */ #ifndef _GUI_MAIN_H #define _GUI_MAIN_H #include #include "core.h" #define PLAY 1 #define PAUSE 2 void flush_rb_disk2gui(void); void try_waking_disk_thread(void); void toggle_noeffect(int id, int state); void cue_track_for_playback(GtkTreeStore * store, GtkTreeIter * piter, cue_t * cue); void create_gui(int argc, char ** argv, int optind, int enqueue, unsigned long rate, unsigned long rb_audio_size); void run_gui(void); void format_bps_label(int bps, int format_flags, char * str); void refresh_displays(void); void main_window_set_font(int cond); void save_window_position(void); void restore_window_position(void); void main_buttons_set_content(char * skin_path); void set_src_type_label(int src_type); gint scroll_btn_pressed(GtkWidget * widget, GdkEventButton * event); gint scroll_btn_released(GtkWidget * widget, GdkEventButton * event, gpointer * win); gint scroll_motion_notify(GtkWidget * widget, GdkEventMotion * event, gpointer * win); void set_buttons_relief(void); void hide_cover_thumbnail(void); #endif /* _GUI_MAIN_H */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/gui_main.c0000644000175000001440000033101111324131225013626 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: gui_main.c 1098 2010-01-10 19:52:40Z peterszilagyi $ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef _WIN32 #include #else #include #endif /* _WIN32 */ #ifdef HAVE_LADSPA #include #endif /* HAVE_LADSPA */ #ifdef HAVE_SRC #include #endif /* HAVE_SRC */ #ifdef HAVE_LUA #include "ext_title_format.h" #endif /* HAVE_LUA */ #include "common.h" #include "utils.h" #include "utils_gui.h" #include "core.h" #include "rb.h" #include "cover.h" #include "transceiver.h" #include "decoder/file_decoder.h" #include "about.h" #include "options.h" #include "skin.h" #include "ports.h" #include "music_browser.h" #include "store_file.h" #include "store_podcast.h" #include "playlist.h" #include "plugin.h" #include "file_info.h" #include "i18n.h" #include "cdda.h" #include "store_cdda.h" #include "loop_bar.h" #include "httpc.h" #include "metadata.h" #include "gui_main.h" #include "version.h" /* receive at most this much remote messages in one run of timeout_callback() */ #define MAX_RCV_COUNT 32 /* period of main timeout callback [ms] */ #define TIMEOUT_PERIOD 100 extern options_t options; char pl_color_active[14]; char pl_color_inactive[14]; PangoFontDescription *fd_playlist; PangoFontDescription *fd_browser; PangoFontDescription *fd_bigtimer; PangoFontDescription *fd_smalltimer; PangoFontDescription *fd_songtitle; PangoFontDescription *fd_songinfo; PangoFontDescription *fd_statusbar; /* Communication between gui thread and disk thread */ extern AQUALUNG_MUTEX_DECLARE(disk_thread_lock) extern AQUALUNG_COND_DECLARE(disk_thread_wake) extern rb_t * rb_gui2disk; extern rb_t * rb_disk2gui; #ifdef HAVE_JACK extern jack_client_t * jack_client; extern char * client_name; extern int jack_is_shutdown; #endif /* HAVE_JACK */ extern int aqualung_socket_fd; extern int aqualung_session_id; extern GtkTreeStore * music_store; extern GtkListStore * running_store; extern GtkWidget * plist_menu; extern GtkWidget * playlist_notebook; void init_plist_menu(GtkWidget *append_menu); /* the physical name of the file that is playing, or a '\0'. */ char current_file[MAXLEN]; /* embedded picture in the file that is playing */ void * embedded_picture = NULL; int embedded_picture_size = 0; /* default window title */ char win_title[MAXLEN]; char send_cmd, recv_cmd; char command[RB_CONTROL_SIZE]; fileinfo_t fileinfo; status_t status; unsigned long out_SR; extern int output; unsigned long rb_size; unsigned long long total_samples; unsigned long long sample_pos; /* this flag set to 1 in core.c if --play for current instance is specified. */ int immediate_start = 0; /* Whether to stop playing after currently played song ends. */ int stop_after_current_song = 0; /* Whether the systray is used in this instance */ int systray_used = 0; /* the tab to load remote files */ char * tab_name; /* volume & balance sliders */ double vol_prev = 0.0f; double vol_lin = 1.0f; double bal_prev = 0.0f; extern double left_gain; extern double right_gain; /* label/display data */ fileinfo_t disp_info; unsigned long disp_samples; unsigned long disp_pos; GtkWidget * main_window; extern GtkWidget * browser_window; extern GtkWidget * playlist_window; extern GtkWidget * fxbuilder_window; extern GtkWidget * ports_window; extern GtkWidget * vol_window; extern GtkWidget * browser_paned; extern int music_store_changed; extern int fxbuilder_on; GtkObject * adj_pos; GtkObject * adj_vol; GtkObject * adj_bal; GtkWidget * scale_pos; GtkWidget * scale_vol; GtkWidget * scale_bal; GtkWidget * vbox_sep; #ifdef HAVE_LOOP GtkWidget * loop_bar; #endif /* HAVE_LOOP */ GtkWidget * time_labels[3]; int refresh_time_label = 1; gulong play_id; gulong pause_id; GtkWidget * play_button; GtkWidget * pause_button; GtkWidget * prev_button; GtkWidget * stop_button; GtkWidget * next_button; GtkWidget * repeat_button; GtkWidget * repeat_all_button; GtkWidget * shuffle_button; GtkWidget * label_title; GtkWidget * label_format; GtkWidget * label_samplerate; GtkWidget * label_bps; GtkWidget * label_mono; GtkWidget * label_output; GtkWidget * label_src_type; int x_scroll_start; int x_scroll_pos; int scroll_btn; GtkWidget * plugin_toggle; GtkWidget * musicstore_toggle; GtkWidget * playlist_toggle; guint timeout_tag; guint vol_bal_timeout_tag = 0; gint timeout_callback(gpointer data); /* whether we are refreshing the scale on STATUS commands recv'd from disk thread */ int refresh_scale = 1; /* suppress scale refreshing after seeking (discard this much STATUS packets). Prevents position slider to momentarily jump back to original position. */ int refresh_scale_suppress = 0; /* whether we allow seeks (depending on if we are at the end of the track) */ int allow_seeks = 1; /* controls when to load the new file's data on display */ int fresh_new_file = 1; int fresh_new_file_prev = 1; /* whether we have a file loaded, that is currently playing (or paused) */ int is_file_loaded = 0; /* whether playback is paused */ int is_paused = 0; /* popup menu for configuration */ GtkWidget * conf_menu; GtkWidget * conf__options; GtkWidget * conf__skin; GtkWidget * conf__jack; GtkWidget * conf__fileinfo; GtkWidget * conf__about; GtkWidget * conf__quit; GtkWidget * bigtimer_label; GtkWidget * smalltimer_label_1; GtkWidget * smalltimer_label_2; /* systray stuff */ #ifdef HAVE_SYSTRAY GtkStatusIcon * systray_icon; GtkWidget * systray_menu; GtkWidget * systray__show; GtkWidget * systray__hide; GtkWidget * systray__play; GtkWidget * systray__pause; GtkWidget * systray__stop; GtkWidget * systray__prev; GtkWidget * systray__next; GtkWidget * systray__quit; int wm_not_systray_capable = 0; void hide_all_windows(gpointer data); #if (GTK_CHECK_VERSION(2,15,0)) /* Used for not reacting too quickly to consecutive mouse wheel events */ guint32 last_systray_scroll_event_time = 0; #endif /* GTK_CHECK_VERSION */ #endif /* HAVE_SYSTRAY */ int systray_main_window_on = 1; void create_main_window(char * skin_path); void toggle_noeffect(int id, int state); gint prev_event(GtkWidget * widget, GdkEvent * event, gpointer data); gint play_event(GtkWidget * widget, GdkEvent * event, gpointer data); gint pause_event(GtkWidget * widget, GdkEvent * event, gpointer data); gint stop_event(GtkWidget * widget, GdkEvent * event, gpointer data); gint next_event(GtkWidget * widget, GdkEvent * event, gpointer data); void load_config(void); void playlist_toggled(GtkWidget * widget, gpointer data); GtkWidget * cover_align; GtkWidget * c_event_box; GtkWidget * cover_image_area; gint cover_show_flag; extern char fileinfo_name[MAXLEN]; extern char fileinfo_file[MAXLEN]; extern GtkWidget * plist__fileinfo; extern GtkWidget * plist__rva; extern gint playlist_state; extern gint browser_state; void try_waking_disk_thread(void) { if (AQUALUNG_MUTEX_TRYLOCK(disk_thread_lock)) { AQUALUNG_COND_SIGNAL(disk_thread_wake) AQUALUNG_MUTEX_UNLOCK(disk_thread_lock) } } void set_title_label(char * str) { gchar default_title[MAXLEN]; char tmp[MAXLEN]; tmp[0] = '\0'; if (is_file_loaded) { gtk_label_set_text(GTK_LABEL(label_title), str); if (options.show_sn_title) { if (stop_after_current_song) { strncat(tmp, "[", MAXLEN-1); strncat(tmp, _("STOPPING"), MAXLEN-1); strncat(tmp, "] ", MAXLEN-1); } strncat(tmp, str, MAXLEN-1); strncat(tmp, " - ", MAXLEN-1); strncat(tmp, win_title, MAXLEN-1); gtk_window_set_title(GTK_WINDOW(main_window), tmp); #ifdef HAVE_SYSTRAY if (systray_used) { aqualung_status_icon_set_tooltip_text(systray_icon, tmp); } #endif /* HAVE_SYSTRAY */ } else { gtk_window_set_title(GTK_WINDOW(main_window), win_title); #ifdef HAVE_SYSTRAY if (systray_used) { aqualung_status_icon_set_tooltip_text(systray_icon, win_title); } #endif /* HAVE_SYSTRAY */ } } else { sprintf(default_title, "Aqualung %s", AQUALUNG_VERSION); gtk_label_set_text(GTK_LABEL(label_title), default_title); gtk_window_set_title(GTK_WINDOW(main_window), win_title); #ifdef HAVE_SYSTRAY if (systray_used) { aqualung_status_icon_set_tooltip_text(systray_icon, win_title); } #endif /* HAVE_SYSTRAY */ } } void hide_cover_thumbnail(void) { cover_show_flag = 0; gtk_widget_hide(cover_image_area); gtk_widget_hide(c_event_box); gtk_widget_hide(cover_align); } void set_format_label(char * format_str) { if (!is_file_loaded) { gtk_label_set_text(GTK_LABEL(label_format), ""); } else { gtk_label_set_text(GTK_LABEL(label_format), format_str); } } void format_bps_label(int bps, int format_flags, char * str) { if (bps == 0) { strcpy(str, "N/A kbit/s"); return; } if (format_flags & FORMAT_VBR) { sprintf(str, "%.1f kbit/s VBR", bps/1000.0); } else { if (format_flags & FORMAT_UBR) { sprintf(str, "%.1f kbit/s UBR", bps/1000.0); } else { sprintf(str, "%.1f kbit/s", bps/1000.0); } } } void set_bps_label(int bps, int format_flags) { char str[MAXLEN]; format_bps_label(bps, format_flags, str); if (is_file_loaded) { gtk_label_set_text(GTK_LABEL(label_bps), str); } else { gtk_label_set_text(GTK_LABEL(label_bps), ""); } } void set_samplerate_label(int sr) { char str[MAXLEN]; snprintf(str, MAXLEN-1, "%d Hz", sr); if (is_file_loaded) { gtk_label_set_text(GTK_LABEL(label_samplerate), str); } else { gtk_label_set_text(GTK_LABEL(label_samplerate), ""); } } void set_mono_label(int is_mono) { if (is_file_loaded) { if (is_mono) { gtk_label_set_text(GTK_LABEL(label_mono), _("MONO")); } else { gtk_label_set_text(GTK_LABEL(label_mono), _("STEREO")); } } else { gtk_label_set_text(GTK_LABEL(label_mono), ""); } } void set_output_label(int output, int out_SR) { char str[MAXLEN]; switch (output) { #ifdef HAVE_PULSE case PULSE_DRIVER: snprintf(str, MAXLEN-1, "%s PulseAudio @ %d Hz", _("Output:"), out_SR); break; #endif /* HAVE_PULSE */ #ifdef HAVE_SNDIO case SNDIO_DRIVER: snprintf(str, MAXLEN-1, "%s sndio @ %d Hz", _("Output:"), out_SR); break; #endif /* HAVE_SNDIO */ #ifdef HAVE_OSS case OSS_DRIVER: snprintf(str, MAXLEN-1, "%s OSS @ %d Hz", _("Output:"), out_SR); break; #endif /* HAVE_OSS */ #ifdef HAVE_ALSA case ALSA_DRIVER: snprintf(str, MAXLEN-1, "%s ALSA @ %d Hz", _("Output:"), out_SR); break; #endif /* HAVE_ALSA */ #ifdef HAVE_JACK case JACK_DRIVER: snprintf(str, MAXLEN-1, "%s JACK @ %d Hz", _("Output:"), out_SR); break; #endif /* HAVE_JACK */ #ifdef _WIN32 case WIN32_DRIVER: snprintf(str, MAXLEN-1, "%s Win32 @ %d Hz", _("Output:"), out_SR); break; #endif /* _WIN32 */ default: strncpy(str, _("No output"), MAXLEN-1); break; } gtk_label_set_text(GTK_LABEL(label_output), str); } void set_src_type_label(int src_type) { char str[MAXLEN]; strcpy(str, _("SRC Type: ")); #ifdef HAVE_SRC strcat(str, src_get_name(src_type)); #else strcat(str, _("None")); #endif /* HAVE_SRC */ gtk_label_set_text(GTK_LABEL(label_src_type), str); } void refresh_time_displays(void) { char str[MAXLEN]; if (is_file_loaded) { if (refresh_time_label || options.time_idx[0] != 0) { sample2time(disp_info.sample_rate, disp_pos, str, 0); gtk_label_set_text(GTK_LABEL(time_labels[0]), str); } if (refresh_time_label || options.time_idx[0] != 1) { if (disp_samples == 0) { strcpy(str, " N/A "); } else { sample2time(disp_info.sample_rate, disp_samples - disp_pos, str, 1); } gtk_label_set_text(GTK_LABEL(time_labels[1]), str); } if (refresh_time_label || options.time_idx[0] != 2) { if (disp_samples == 0) { strcpy(str, " N/A "); } else { sample2time(disp_info.sample_rate, disp_samples, str, 0); } gtk_label_set_text(GTK_LABEL(time_labels[2]), str); } } else { int i; for (i = 0; i < 3; i++) { gtk_label_set_text(GTK_LABEL(time_labels[i]), " 00:00 "); } } } #ifdef HAVE_LOOP void loop_bar_update_tooltip(void) { if (options.enable_tooltips) { char str[MAXLEN]; if (is_file_loaded) { char start[32]; char end[32]; sample2time(disp_info.sample_rate, total_samples * options.loop_range_start, start, 0); sample2time(disp_info.sample_rate, total_samples * options.loop_range_end, end, 0); snprintf(str, MAXLEN-1, _("Loop range: %d-%d%% [%s - %s]"), (int)(100 * options.loop_range_start), (int)(100 * options.loop_range_end), start, end); } else { snprintf(str, MAXLEN-1, _("Loop range: %d-%d%%"), (int)(100 * options.loop_range_start), (int)(100 * options.loop_range_end)); } aqualung_widget_set_tooltip_text(loop_bar, str); } } void loop_range_changed_cb(AqualungLoopBar * bar, float start, float end, gpointer data) { options.loop_range_start = start; options.loop_range_end = end; loop_bar_update_tooltip(); } #endif /* HAVE_LOOP */ void refresh_displays(void) { GtkTreePath * p; GtkTreeIter iter; playlist_t * pl; refresh_time_displays(); #ifdef HAVE_LOOP loop_bar_update_tooltip(); #endif /* HAVE_LOOP */ set_format_label(disp_info.format_str); set_samplerate_label(disp_info.sample_rate); set_bps_label(disp_info.bps, disp_info.format_flags); set_mono_label(disp_info.is_mono); set_output_label(output, out_SR); set_src_type_label(options.src_type); if ((pl = playlist_get_playing()) == NULL) { if ((pl = playlist_get_current()) == NULL) { set_title_label(""); hide_cover_thumbnail(); return; } } p = playlist_get_playing_path(pl); if (p != NULL) { playlist_data_t * pldata; gtk_tree_model_get_iter(GTK_TREE_MODEL(pl->store), &iter, p); gtk_tree_model_get(GTK_TREE_MODEL(pl->store), &iter, PL_COL_DATA, &pldata, -1); gtk_tree_path_free(p); if (!httpc_is_url(pldata->file) && !options.use_ext_title_format) { char list_str[MAXLEN]; playlist_data_get_display_name(list_str, pldata); set_title_label(list_str); } else if (!is_file_loaded) { char * name; gtk_tree_model_get(GTK_TREE_MODEL(pl->store), &iter, PL_COL_NAME, &name, -1); set_title_label(name); g_free(name); } if (is_file_loaded) { if (!options.dont_show_cover) { if (embedded_picture != NULL) { display_cover_from_binary(cover_image_area, c_event_box, cover_align, 48, 48, embedded_picture, embedded_picture_size, TRUE, TRUE); } else { if (options.show_cover_for_ms_tracks_only) { if (IS_PL_COVER(pldata)) { display_cover(cover_image_area, c_event_box, cover_align, 48, 48, pldata->file, TRUE, TRUE); } else { hide_cover_thumbnail(); } } else { display_cover(cover_image_area, c_event_box, cover_align, 48, 48, pldata->file, TRUE, TRUE); } } } } } else if (!is_file_loaded) { set_title_label(""); hide_cover_thumbnail(); } } void zero_displays(void) { disp_info.total_samples = 0; disp_info.sample_rate = 0; disp_info.channels = 2; disp_info.is_mono = 0; disp_info.bps = 0; disp_samples = 0; disp_pos = 0; refresh_displays(); } void save_window_position(void) { gtk_window_get_position(GTK_WINDOW(main_window), &options.main_pos_x, &options.main_pos_y); if (!options.playlist_is_embedded && options.playlist_on) { gtk_window_get_position(GTK_WINDOW(playlist_window), &options.playlist_pos_x, &options.playlist_pos_y); } if (options.browser_on) { gtk_window_get_position(GTK_WINDOW(browser_window), &options.browser_pos_x, &options.browser_pos_y); } gtk_window_get_size(GTK_WINDOW(main_window), &options.main_size_x, &options.main_size_y); gtk_window_get_size(GTK_WINDOW(browser_window), &options.browser_size_x, &options.browser_size_y); if (!options.playlist_is_embedded) { gtk_window_get_size(GTK_WINDOW(playlist_window), &options.playlist_size_x, &options.playlist_size_y); } else { options.playlist_size_x = playlist_window->allocation.width; options.playlist_size_y = playlist_window->allocation.height; } if (!options.hide_comment_pane) { options.browser_paned_pos = gtk_paned_get_position(GTK_PANED(browser_paned)); } } void restore_window_position(void) { gtk_window_move(GTK_WINDOW(main_window), options.main_pos_x, options.main_pos_y); gtk_window_move(GTK_WINDOW(browser_window), options.browser_pos_x, options.browser_pos_y); if (!options.playlist_is_embedded) { gtk_window_move(GTK_WINDOW(playlist_window), options.playlist_pos_x, options.playlist_pos_y); } gtk_window_resize(GTK_WINDOW(main_window), options.main_size_x, options.main_size_y); gtk_window_resize(GTK_WINDOW(browser_window), options.browser_size_x, options.browser_size_y); if (!options.playlist_is_embedded) { gtk_window_resize(GTK_WINDOW(playlist_window), options.playlist_size_x, options.playlist_size_y); } if (!options.hide_comment_pane) { gtk_paned_set_position(GTK_PANED(browser_paned), options.browser_paned_pos); } } gboolean main_window_close(GtkWidget * widget, GdkEvent * event, gpointer data) { send_cmd = CMD_FINISH; rb_write(rb_gui2disk, &send_cmd, 1); try_waking_disk_thread(); #ifdef HAVE_CDDA cdda_shutdown(); #endif /* HAVE_CDDA */ if (systray_main_window_on) { save_window_position(); } save_config(); #ifdef HAVE_LADSPA save_plugin_data(); lrdf_cleanup(); #endif /* HAVE_LADSPA */ #ifdef HAVE_SYSTRAY if (systray_used) { gtk_status_icon_set_visible(GTK_STATUS_ICON(systray_icon), FALSE); } #endif /* HAVE_SYSTRAY */ if (options.auto_save_playlist) { char playlist_name[MAXLEN]; snprintf(playlist_name, MAXLEN-1, "%s/%s", options.confdir, "playlist.xml"); playlist_save_all(playlist_name); } pango_font_description_free(fd_playlist); pango_font_description_free(fd_browser); finalize_options(); gtk_main_quit(); return FALSE; } void main_window_closing(void) { if (music_store_changed) { GtkWidget * dialog; int resp; dialog = gtk_message_dialog_new(GTK_WINDOW(main_window), GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE, _("One or more stores in Music Store have been modified.\n" "Do you want to save them before exiting?")); gtk_dialog_add_buttons(GTK_DIALOG(dialog), _("Save"), GTK_RESPONSE_YES, _("Discard changes"), GTK_RESPONSE_NO, _("Do not exit"), GTK_RESPONSE_CANCEL, NULL); gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER); gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_YES); gtk_container_set_border_width(GTK_CONTAINER(dialog), 5); gtk_window_set_title(GTK_WINDOW(dialog), _("Quit")); resp = aqualung_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); if (resp == GTK_RESPONSE_CANCEL) { return; } if (resp == GTK_RESPONSE_YES) { music_store_save_all(); } } main_window_close(NULL, NULL, NULL); } gboolean main_window_event(GtkWidget * widget, GdkEvent * event, gpointer data) { if (event->type == GDK_DELETE) { #ifdef HAVE_SYSTRAY if (systray_used) { hide_all_windows(NULL); } else { main_window_closing(); } #else main_window_closing(); #endif /* HAVE_SYSTRAY */ return TRUE; } return FALSE; } void main_window_resize(void) { if (options.playlist_is_embedded && !options.playlist_on) { gtk_window_resize(GTK_WINDOW(main_window), options.main_size_x, options.main_size_y - 14 - 6 - 6 - playlist_window->allocation.height); } if (!options.playlist_is_embedded) { gtk_window_resize(GTK_WINDOW(main_window), options.main_size_x, options.main_size_y - 14 - 6); } } /***********************************************************************************/ void conf__options_cb(gpointer data) { create_options_window(); } void conf__skin_cb(gpointer data) { create_skin_window(); } void conf__jack_cb(gpointer data) { #ifdef HAVE_JACK port_setup_dialog(); #endif /* HAVE_JACK */ } void conf__fileinfo_cb(gpointer data) { if (is_file_loaded) { GtkTreeIter dummy; const char * name = gtk_label_get_text(GTK_LABEL(label_title)); show_file_info((char *)name, current_file, 0, NULL, dummy, TRUE); } } void conf__about_cb(gpointer data) { create_about_window(); } void conf__quit_cb(gpointer data) { main_window_closing(); } gint vol_bal_timeout_callback(gpointer data) { refresh_time_label = 1; vol_bal_timeout_tag = 0; refresh_time_displays(); return FALSE; } void musicstore_toggled(GtkWidget * widget, gpointer data) { if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) { show_music_browser(); } else { hide_music_browser(); } } void playlist_toggled(GtkWidget * widget, gpointer data) { if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) { show_playlist(); } else { hide_playlist(); } } void plugin_toggled(GtkWidget * widget, gpointer data) { #ifdef HAVE_LADSPA if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) { show_fxbuilder(); } else { hide_fxbuilder(); } #else /* XXX */ printf("Aqualung compiled without LADSPA plugin support.\n"); #endif /* HAVE_LADSPA */ } void toggle_stop_after_current_song() { if (is_file_loaded) { stop_after_current_song = !stop_after_current_song; refresh_displays(); } } void move_song_position_slider(GtkScrollType scroll_type) { if (is_file_loaded && allow_seeks && total_samples != 0) { refresh_scale = 0; g_signal_emit_by_name(G_OBJECT(scale_pos), "move-slider", scroll_type, NULL); } } void seek_song(void) { if (is_file_loaded && allow_seeks && refresh_scale == 0 && total_samples != 0) { seek_t seek; refresh_scale = 1; send_cmd = CMD_SEEKTO; seek.seek_to_pos = gtk_adjustment_get_value(GTK_ADJUSTMENT(adj_pos)) / 100.0f * total_samples; rb_write(rb_gui2disk, &send_cmd, 1); rb_write(rb_gui2disk, (char *)&seek, sizeof(seek_t)); try_waking_disk_thread(); refresh_scale_suppress = 2; } } void change_volume_or_balance(GtkWidget * slider_widget, GtkScrollType scroll_type) { refresh_time_label = 0; if (vol_bal_timeout_tag) { g_source_remove(vol_bal_timeout_tag); } vol_bal_timeout_tag = aqualung_timeout_add(1000, vol_bal_timeout_callback, NULL); g_signal_emit_by_name(G_OBJECT(slider_widget), "move-slider", scroll_type, NULL); } gint main_window_key_pressed(GtkWidget * widget, GdkEventKey * event) { int playlist_tabs = gtk_notebook_get_n_pages(GTK_NOTEBOOK(playlist_notebook)); switch (event->keyval) { case GDK_KP_Divide: case GDK_slash: if (event->state & GDK_MOD1_MASK) { /* ALT + KP_Divide */ change_volume_or_balance(scale_bal, GTK_SCROLL_STEP_BACKWARD); } else { change_volume_or_balance(scale_vol, GTK_SCROLL_STEP_BACKWARD); } return TRUE; case GDK_KP_Multiply: case GDK_asterisk: if (event->state & GDK_MOD1_MASK) { /* ALT + KP_Multiply */ change_volume_or_balance(scale_bal, GTK_SCROLL_STEP_FORWARD); } else { change_volume_or_balance(scale_vol, GTK_SCROLL_STEP_FORWARD); } return TRUE; case GDK_Right: move_song_position_slider(GTK_SCROLL_STEP_FORWARD); return TRUE; case GDK_Left: move_song_position_slider(GTK_SCROLL_STEP_BACKWARD); return TRUE; case GDK_b: case GDK_B: case GDK_period: next_event(NULL, NULL, NULL); return TRUE; case GDK_z: case GDK_Z: case GDK_y: case GDK_Y: case GDK_comma: prev_event(NULL, NULL, NULL); return TRUE; case GDK_s: case GDK_S: if (event->state & GDK_MOD1_MASK) { /* ALT + s */ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(musicstore_toggle), !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(musicstore_toggle))); } else { if (!(event->state & GDK_CONTROL_MASK)) { stop_event(NULL, NULL, NULL); } else { toggle_stop_after_current_song(); } } return TRUE; case GDK_v: case GDK_V: if (!(event->state & GDK_CONTROL_MASK)) { stop_event(NULL, NULL, NULL); return TRUE; } break; case GDK_c: case GDK_C: case GDK_space: if (!(event->state & GDK_CONTROL_MASK)) { if (!options.combine_play_pause) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pause_button), !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(pause_button))); } else if (is_file_loaded) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(play_button), !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(play_button))); } return TRUE; } break; case GDK_p: case GDK_P: gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(play_button), !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(play_button))); return TRUE; case GDK_i: case GDK_I: if (!options.playlist_is_embedded) { conf__fileinfo_cb(NULL); return TRUE; } break; case GDK_BackSpace: if (allow_seeks && total_samples != 0) { seek_t seek; send_cmd = CMD_SEEKTO; seek.seek_to_pos = 0.0f; rb_write(rb_gui2disk, &send_cmd, 1); rb_write(rb_gui2disk, (char *)&seek, sizeof(seek_t)); try_waking_disk_thread(); refresh_scale_suppress = 2; } if ((!options.combine_play_pause) && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(pause_button))) { gtk_adjustment_set_value(GTK_ADJUSTMENT(adj_pos), 0.0f); } return TRUE; case GDK_l: case GDK_L: if (event->state & GDK_MOD1_MASK) { /* ALT + l */ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(playlist_toggle), !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(playlist_toggle))); } return TRUE; case GDK_x: case GDK_X: if (event->state & GDK_CONTROL_MASK) { break; } if (event->state & GDK_MOD1_MASK) { /* ALT + x */ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(plugin_toggle), !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(plugin_toggle))); } else { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(play_button), !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(play_button))); } return TRUE; case GDK_q: case GDK_Q: if (event->state & GDK_CONTROL_MASK) { /* CTRL + q */ main_window_closing(); } return TRUE; case GDK_k: case GDK_K: if (!options.disable_skin_support_settings) { create_skin_window(); } return TRUE; case GDK_o: case GDK_O: create_options_window(); return TRUE; case GDK_1: if (event->state & GDK_MOD1_MASK) { /* ALT + 1 */ if(playlist_tabs >= 1) { gtk_notebook_set_current_page(GTK_NOTEBOOK(playlist_notebook), 1-1); } } else { if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(repeat_button))) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(repeat_button), FALSE); } else { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(repeat_button), TRUE); } } return TRUE; case GDK_2: if (event->state & GDK_MOD1_MASK) { /* ALT + 2 */ if(playlist_tabs >= 2) { gtk_notebook_set_current_page(GTK_NOTEBOOK(playlist_notebook), 2-1); } } else { if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(repeat_all_button))) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(repeat_all_button), FALSE); } else { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(repeat_all_button), TRUE); } } return TRUE; case GDK_3: if (event->state & GDK_MOD1_MASK) { /* ALT + 3 */ if(playlist_tabs >= 3) { gtk_notebook_set_current_page(GTK_NOTEBOOK(playlist_notebook), 3-1); } } else { if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(shuffle_button))) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(shuffle_button), FALSE); } else { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(shuffle_button), TRUE); } } return TRUE; case GDK_4: case GDK_5: case GDK_6: case GDK_7: case GDK_8: case GDK_9: case GDK_0: if (event->state & GDK_MOD1_MASK) { /* ALT */ int val = event->keyval - GDK_0; val = (val == 0) ? 10 : val; if(playlist_tabs >= val) { gtk_notebook_set_current_page(GTK_NOTEBOOK(playlist_notebook), val-1); } } return TRUE; #ifdef HAVE_SYSTRAY case GDK_Escape: if (systray_used) { hide_all_windows(NULL); } return TRUE; #endif /* HAVE_SYSTRAY */ #ifdef HAVE_LOOP case GDK_less: if (options.repeat_on && is_file_loaded) { float pos = (total_samples > 0) ? ((double)sample_pos / total_samples) : 0; aqualung_loop_bar_adjust_start(AQUALUNG_LOOP_BAR(loop_bar), pos); } return TRUE; case GDK_greater: if (options.repeat_on && is_file_loaded) { float pos = (total_samples > 0) ? ((double)sample_pos / total_samples) : 1; aqualung_loop_bar_adjust_end(AQUALUNG_LOOP_BAR(loop_bar), pos); } return TRUE; #endif /* HAVE_LOOP */ } if (options.playlist_is_embedded) { playlist_window_key_pressed(widget, event); } return FALSE; } gint main_window_key_released(GtkWidget * widget, GdkEventKey * event) { switch (event->keyval) { case GDK_Right: case GDK_Left: seek_song(); break; } return FALSE; } gint main_window_focus_out(GtkWidget * widget, GdkEventFocus * event, gpointer data) { refresh_scale = 1; return FALSE; } gint main_window_state_changed(GtkWidget * widget, GdkEventWindowState * event, gpointer data) { if (!options.united_minimization) return FALSE; if (event->new_window_state == GDK_WINDOW_STATE_ICONIFIED) { if (options.browser_on) { gtk_window_iconify(GTK_WINDOW(browser_window)); } if (!options.playlist_is_embedded && options.playlist_on) { gtk_window_iconify(GTK_WINDOW(playlist_window)); } if (vol_window) { gtk_window_iconify(GTK_WINDOW(vol_window)); } #ifdef HAVE_LADSPA if (fxbuilder_on) { GtkTreeIter iter; gpointer gp_instance; int i = 0; gtk_window_iconify(GTK_WINDOW(fxbuilder_window)); while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(running_store), &iter, NULL, i) && i < MAX_PLUGINS) { gtk_tree_model_get(GTK_TREE_MODEL(running_store), &iter, 1, &gp_instance, -1); gtk_widget_hide(((plugin_instance *)gp_instance)->window); ++i; } } #endif /* HAVE_LADSPA */ } if (event->new_window_state == 0) { if (options.browser_on) { gtk_window_deiconify(GTK_WINDOW(browser_window)); } if (!options.playlist_is_embedded && options.playlist_on) { gtk_window_deiconify(GTK_WINDOW(playlist_window)); } if (vol_window) { gtk_window_deiconify(GTK_WINDOW(vol_window)); } if (fxbuilder_on) { gtk_window_deiconify(GTK_WINDOW(fxbuilder_window)); } } return FALSE; } gint main_window_button_pressed(GtkWidget * widget, GdkEventButton * event) { if (event->button == 3) { GtkWidget * fileinfo; if (options.playlist_is_embedded) { fileinfo = plist__fileinfo; } else { fileinfo = conf__fileinfo; } if (is_file_loaded && (current_file[0] != '\0')) { const char * name = gtk_label_get_text(GTK_LABEL(label_title)); strncpy(fileinfo_name, name, MAXLEN-1); strncpy(fileinfo_file, current_file, MAXLEN-1); gtk_widget_set_sensitive(fileinfo, TRUE); } else { gtk_widget_set_sensitive(fileinfo, FALSE); } if (options.playlist_is_embedded) { playlist_menu_set_popup_sensitivity(playlist_get_current()); } gtk_menu_popup(GTK_MENU(conf_menu), NULL, NULL, NULL, NULL, event->button, event->time); } return TRUE; } static gint scale_button_press_event(GtkWidget * widget, GdkEventButton * event) { if (event->button == 3) return FALSE; if (!is_file_loaded) return FALSE; if (!allow_seeks) return FALSE; if (total_samples == 0) return FALSE; refresh_scale = 0; return FALSE; } static gint scale_button_release_event(GtkWidget * widget, GdkEventButton * event) { seek_t seek; if (is_file_loaded) { if (!allow_seeks) return FALSE; if (total_samples == 0) return FALSE; if (refresh_scale == 0) { refresh_scale = 1; send_cmd = CMD_SEEKTO; seek.seek_to_pos = gtk_adjustment_get_value(GTK_ADJUSTMENT(adj_pos)) / 100.0f * total_samples; rb_write(rb_gui2disk, &send_cmd, 1); rb_write(rb_gui2disk, (char *)&seek, sizeof(seek_t)); try_waking_disk_thread(); refresh_scale_suppress = 2; } } return FALSE; } void changed_pos(GtkAdjustment * adj, gpointer data) { static int pos = -1; if (!is_file_loaded) { gtk_adjustment_set_value(adj, 0.0f); } if (options.enable_tooltips) { int newpos = (int)gtk_adjustment_get_value(adj); if (pos != newpos) { char str[32]; snprintf(str, 31, _("Position: %d%%"), newpos); aqualung_widget_set_tooltip_text(scale_pos, str); pos = newpos; } } } gint scale_vol_button_press_event(GtkWidget * widget, GdkEventButton * event) { char str[32]; options.vol = gtk_adjustment_get_value(GTK_ADJUSTMENT(adj_vol)); if (event->state & GDK_SHIFT_MASK) { /* SHIFT */ gtk_adjustment_set_value(GTK_ADJUSTMENT(adj_vol), 0); return TRUE; } if (options.vol < -40.5f) { snprintf(str, 31, _("Mute")); } else { snprintf(str, 31, _("%d dB"), (int)options.vol); } gtk_label_set_text(GTK_LABEL(time_labels[options.time_idx[0]]), str); refresh_time_label = 0; if (event->button == 3) { return TRUE; } else { return FALSE; } } void changed_vol(GtkAdjustment * adj, gpointer date) { char str[32]; char str2[32]; options.vol = (int)gtk_adjustment_get_value(GTK_ADJUSTMENT(adj_vol)); gtk_adjustment_set_value(GTK_ADJUSTMENT(adj_vol), options.vol); if (options.vol < -40.5f) { snprintf(str, 31, _("Mute")); } else { snprintf(str, 31, _("%d dB"), (int)options.vol); } if (!refresh_time_label) { gtk_label_set_text(GTK_LABEL(time_labels[options.time_idx[0]]), str); } snprintf(str2, 31, _("Volume: %s"), str); aqualung_widget_set_tooltip_text(scale_vol, str2); } gint scale_vol_button_release_event(GtkWidget * widget, GdkEventButton * event) { refresh_time_label = 1; refresh_time_displays(); return FALSE; } gint scale_bal_button_press_event(GtkWidget * widget, GdkEventButton * event) { char str[32]; options.bal = gtk_adjustment_get_value(GTK_ADJUSTMENT(adj_bal)); if (event->state & GDK_SHIFT_MASK) { /* SHIFT */ gtk_adjustment_set_value(GTK_ADJUSTMENT(adj_bal), 0); return TRUE; } if (options.bal != 0.0f) { if (options.bal > 0.0f) { snprintf(str, 31, _("%d%% R"), (int)options.bal); } else { snprintf(str, 31, _("%d%% L"), -1*(int)options.bal); } } else { snprintf(str, 31, _("C")); } gtk_label_set_text(GTK_LABEL(time_labels[options.time_idx[0]]), str); refresh_time_label = 0; if (event->button == 3) { return TRUE; } else { return FALSE; } } void changed_bal(GtkAdjustment * adj, gpointer date) { char str[32]; char str2[32]; options.bal = (int)gtk_adjustment_get_value(GTK_ADJUSTMENT(adj_bal)); gtk_adjustment_set_value(GTK_ADJUSTMENT(adj_bal), options.bal); if (options.bal != 0.0f) { if (options.bal > 0.0f) { snprintf(str, 31, _("%d%% R"), (int)options.bal); } else { snprintf(str, 31, _("%d%% L"), -1*(int)options.bal); } } else { snprintf(str, 31, _("C")); } if (!refresh_time_label) { gtk_label_set_text(GTK_LABEL(time_labels[options.time_idx[0]]), str); } snprintf(str2, 31, _("Balance: %s"), str); aqualung_widget_set_tooltip_text(scale_bal, str2); } gint scale_bal_button_release_event(GtkWidget * widget, GdkEventButton * event) { refresh_time_label = 1; refresh_time_displays(); return FALSE; } void show_scale_pos(gboolean state) { if (state == FALSE) { gtk_widget_hide(GTK_WIDGET(scale_pos)); gtk_widget_show(GTK_WIDGET(vbox_sep)); main_window_resize(); } else { gtk_widget_show(GTK_WIDGET(scale_pos)); gtk_widget_hide(GTK_WIDGET(vbox_sep)); } } /******** Cue functions *********/ void toggle_noeffect(int id, int state) { switch (id) { case PLAY: g_signal_handler_block(G_OBJECT(play_button), play_id); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(play_button), state); g_signal_handler_unblock(G_OBJECT(play_button), play_id); break; case PAUSE: g_signal_handler_block(G_OBJECT(pause_button), pause_id); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pause_button), state); g_signal_handler_unblock(G_OBJECT(pause_button), pause_id); break; default: printf("error in gui_main.c/toggle_noeffect(): unknown id value %d\n", id); break; } } void cue_track_for_playback(GtkTreeStore * store, GtkTreeIter * piter, cue_t * cue) { playlist_data_t * data; gtk_tree_model_get(GTK_TREE_MODEL(store), piter, PL_COL_DATA, &data, -1); cue->filename = strdup(data->file); cue->voladj = options.rva_is_enabled ? data->voladj : 0.0f; strncpy(current_file, cue->filename, MAXLEN-1); } /* retcode for choose_*_track(): 1->success, 0->empty list */ int choose_first_track(GtkTreeStore * store, GtkTreeIter * piter) { if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), piter)) { if (gtk_tree_model_iter_has_child(GTK_TREE_MODEL(store), piter)) { GtkTreeIter iter_parent = *piter; gtk_tree_model_iter_children(GTK_TREE_MODEL(store), piter, &iter_parent); } return 1; } return 0; } /* get first or last child iter */ void get_child_iter(GtkTreeStore * store, GtkTreeIter * piter, int first) { GtkTreeIter iter; if (first) { gtk_tree_model_iter_children(GTK_TREE_MODEL(store), &iter, piter); } else { int n = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(store), piter); gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(store), &iter, piter, n-1); } *piter = iter; } int choose_prev_track(GtkTreeStore * store, GtkTreeIter * piter) { GtkTreePath * p = gtk_tree_model_get_path(GTK_TREE_MODEL(store), piter); try_again_prev: if (gtk_tree_path_prev(p)) { if (gtk_tree_path_get_depth(p) == 1) { /* toplevel */ GtkTreeIter iter; gtk_tree_model_get_iter(GTK_TREE_MODEL(store), &iter, p); if (gtk_tree_model_iter_has_child(GTK_TREE_MODEL(store), &iter)) { get_child_iter(store, &iter, 0/* last */); } *piter = iter; } else { gtk_tree_model_get_iter(GTK_TREE_MODEL(store), piter, p); } gtk_tree_path_free(p); return 1; } else { if (gtk_tree_path_get_depth(p) == 1) { /* toplevel */ GtkTreeIter iter; int n = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(store), NULL); if (n) { gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(store), &iter, NULL, n-1); if (gtk_tree_model_iter_has_child(GTK_TREE_MODEL(store), &iter)) { get_child_iter(store, &iter, 0/* last */); } *piter = iter; gtk_tree_path_free(p); return 1; } else { gtk_tree_path_free(p); return 0; } } else { gtk_tree_path_up(p); goto try_again_prev; } } } int choose_next_track(GtkTreeStore * store, GtkTreeIter * piter) { GtkTreeIter iter = *piter; if (gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter)) { *piter = iter; if (gtk_tree_model_iter_has_child(GTK_TREE_MODEL(store), piter)) { get_child_iter(store, piter, 1/* first */); } return 1; } else { GtkTreePath * p = gtk_tree_model_get_path(GTK_TREE_MODEL(store), piter); if (gtk_tree_path_get_depth(p) == 1) { /* toplevel */ int n = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(store), NULL); if (n) { gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), piter); if (gtk_tree_model_iter_has_child(GTK_TREE_MODEL(store), piter)) { get_child_iter(store, piter, 1/* first */); } gtk_tree_path_free(p); return 1; } else { gtk_tree_path_free(p); return 0; } } else { gtk_tree_path_up(p); gtk_tree_model_get_iter(GTK_TREE_MODEL(store), piter, p); gtk_tree_path_free(p); return choose_next_track(store, piter); } } } /* simpler case than choose_next_track(); no support for wrap-around at end of list. * used by the timeout callback for track flow-through */ int choose_adjacent_track(GtkTreeStore * store, GtkTreeIter * piter) { GtkTreeIter iter = *piter; if (gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter)) { *piter = iter; if (gtk_tree_model_iter_has_child(GTK_TREE_MODEL(store), piter)) { get_child_iter(store, piter, 1/* first */); } return 1; } else { GtkTreePath * p = gtk_tree_model_get_path(GTK_TREE_MODEL(store), piter); if (gtk_tree_path_get_depth(p) == 1) { /* toplevel */ gtk_tree_path_free(p); return 0; } else { gtk_tree_path_up(p); gtk_tree_model_get_iter(GTK_TREE_MODEL(store), piter, p); gtk_tree_path_free(p); return choose_adjacent_track(store, piter); } } } /* also used to pick the track numbered n_stop in the flattened tree */ long count_playlist_tracks(GtkTreeStore * store, GtkTreeIter * piter, long n_stop) { GtkTreeIter iter; long i = 0; long n = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(store), &iter, NULL, i++)) { long c = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(store), &iter); long d = c; if (!c) ++c; if (n_stop > -1) { if (n_stop > c) { n_stop -= c; } else { if (d) { gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(store), piter, &iter, n_stop-1); } else { *piter = iter; } return 0; } } n += c; } return n; } int random_toplevel_item(GtkTreeStore * store, GtkTreeIter * piter) { long n_items; long n; n_items = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(store), NULL); if (!n_items) { return 0; } n = (double)rand() * n_items / RAND_MAX; if (n == n_items) --n; gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(store), piter, NULL, n); return 1; } int random_first_track(GtkTreeStore * store, GtkTreeIter * piter) { if (random_toplevel_item(store, piter)) { if (gtk_tree_model_iter_has_child(GTK_TREE_MODEL(store), piter)) { get_child_iter(store, piter, 1/* first */); } return 1; } else { return 0; } } int choose_random_track(GtkTreeStore * store, GtkTreeIter * piter) { long n_items; long n; if (options.album_shuffle_mode) { if (gtk_tree_store_iter_is_valid(store, piter)) { int d = gtk_tree_store_iter_depth(store, piter); if (d) { if (gtk_tree_model_iter_next(GTK_TREE_MODEL(store), piter)) { return 1; } } } return random_first_track(store, piter); } else { n_items = count_playlist_tracks(store, NULL, -1); if (n_items) { n = (double)rand() * n_items / RAND_MAX; if (n == n_items) { --n; } count_playlist_tracks(store, piter, n+1); return 1; } return 0; } } void prepare_playback(playlist_t * pl, GtkTreeIter * piter, cue_t * pcue) { mark_track(pl, piter); cue_track_for_playback(pl->store, piter, pcue); is_file_loaded = 1; toggle_noeffect(PLAY, TRUE); } void unprepare_playback(void) { is_file_loaded = 0; stop_after_current_song = 0; current_file[0] = '\0'; zero_displays(); toggle_noeffect(PLAY, FALSE); } gint prev_event(GtkWidget * widget, GdkEvent * event, gpointer data) { GtkTreeIter iter; GtkTreePath * p; char cmd; cue_t cue; playlist_t * pl; if (!allow_seeks) return FALSE; if (is_file_loaded) { pl = playlist_get_playing(); } else { pl = playlist_get_current(); } if (pl == NULL) { return FALSE; } if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(shuffle_button))) { /* normal or repeat mode */ p = playlist_get_playing_path(pl); if (p != NULL) { gtk_tree_model_get_iter(GTK_TREE_MODEL(pl->store), &iter, p); gtk_tree_path_free(p); unmark_track(pl, &iter); if (choose_prev_track(pl->store, &iter)) { mark_track(pl, &iter); } } else { if (choose_first_track(pl->store, &iter)) { mark_track(pl, &iter); } } } else { /* shuffle mode */ p = playlist_get_playing_path(pl); if (p != NULL) { gtk_tree_model_get_iter(GTK_TREE_MODEL(pl->store), &iter, p); gtk_tree_path_free(p); unmark_track(pl, &iter); } if (choose_random_track(pl->store, &iter)) { mark_track(pl, &iter); } } if (is_file_loaded) { if ((p = playlist_get_playing_path(pl)) == NULL) { if (is_paused) { is_paused = 0; toggle_noeffect(PAUSE, FALSE); stop_event(NULL, NULL, NULL); } return FALSE; } gtk_tree_model_get_iter(GTK_TREE_MODEL(pl->store), &iter, p); gtk_tree_path_free(p); cue_track_for_playback(pl->store, &iter, &cue); if (is_paused) { is_paused = 0; toggle_noeffect(PAUSE, FALSE); toggle_noeffect(PLAY, TRUE); } cmd = CMD_CUE; flush_rb_disk2gui(); rb_write(rb_gui2disk, &cmd, sizeof(char)); rb_write(rb_gui2disk, (void *)&cue, sizeof(cue_t)); try_waking_disk_thread(); } return FALSE; } gint next_event(GtkWidget * widget, GdkEvent * event, gpointer data) { GtkTreeIter iter; GtkTreePath * p; char cmd; cue_t cue; playlist_t * pl; if (!allow_seeks) return FALSE; if (is_file_loaded) { pl = playlist_get_playing(); } else { pl = playlist_get_current(); } if (pl == NULL) { return FALSE; } if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(shuffle_button))) { /* normal or repeat mode */ p = playlist_get_playing_path(pl); if (p != NULL) { gtk_tree_model_get_iter(GTK_TREE_MODEL(pl->store), &iter, p); gtk_tree_path_free(p); unmark_track(pl, &iter); if (choose_next_track(pl->store, &iter)) { mark_track(pl, &iter); } } else { if (choose_first_track(pl->store, &iter)) { mark_track(pl, &iter); } } } else { /* shuffle mode */ p = playlist_get_playing_path(pl); if (p != NULL) { gtk_tree_model_get_iter(GTK_TREE_MODEL(pl->store), &iter, p); gtk_tree_path_free(p); unmark_track(pl, &iter); } if (choose_random_track(pl->store, &iter)) { mark_track(pl, &iter); } } if (is_file_loaded) { if ((p = playlist_get_playing_path(pl)) == NULL) { if (is_paused) { is_paused = 0; toggle_noeffect(PAUSE, FALSE); stop_event(NULL, NULL, NULL); } return FALSE; } gtk_tree_model_get_iter(GTK_TREE_MODEL(pl->store), &iter, p); gtk_tree_path_free(p); cue_track_for_playback(pl->store, &iter, &cue); if (is_paused) { is_paused = 0; toggle_noeffect(PAUSE, FALSE); toggle_noeffect(PLAY, TRUE); } cmd = CMD_CUE; flush_rb_disk2gui(); rb_write(rb_gui2disk, &cmd, sizeof(char)); rb_write(rb_gui2disk, (void *)&cue, sizeof(cue_t)); try_waking_disk_thread(); } return FALSE; } gint play_event(GtkWidget * widget, GdkEvent * event, gpointer data) { GtkTreeIter iter; GtkTreePath * p; char cmd; cue_t cue; playlist_t * pl; if (is_paused) { is_paused = 0; if (!options.combine_play_pause) { toggle_noeffect(PAUSE, FALSE); } send_cmd = CMD_RESUME; rb_write(rb_gui2disk, &send_cmd, 1); try_waking_disk_thread(); return FALSE; } if (options.combine_play_pause && is_file_loaded) { return pause_event(widget, event, data); } cmd = CMD_CUE; cue.filename = NULL; while ((pl = playlist_get_playing()) != NULL) { playlist_set_playing(pl, 0); } if ((pl = playlist_get_current()) == NULL) { return FALSE; } playlist_set_playing(pl, 1); p = playlist_get_playing_path(pl); if (p != NULL) { gtk_tree_model_get_iter(GTK_TREE_MODEL(pl->store), &iter, p); gtk_tree_path_free(p); prepare_playback(pl, &iter, &cue); } else { if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(shuffle_button))) { /* normal or repeat mode */ if (choose_first_track(pl->store, &iter)) { prepare_playback(pl, &iter, &cue); } else { unprepare_playback(); } } else { /* shuffle mode */ if (choose_random_track(pl->store, &iter)) { prepare_playback(pl, &iter, &cue); } else { unprepare_playback(); } } } if (cue.filename == NULL) { stop_event(NULL, NULL, NULL); } else { flush_rb_disk2gui(); rb_write(rb_gui2disk, &cmd, sizeof(char)); rb_write(rb_gui2disk, (void *)&cue, sizeof(cue_t)); try_waking_disk_thread(); } return FALSE; } gint pause_event(GtkWidget * widget, GdkEvent * event, gpointer data) { if ((!allow_seeks) || (!is_file_loaded)) { if (!options.combine_play_pause) { toggle_noeffect(PAUSE, FALSE); } return FALSE; } if (!is_paused) { is_paused = 1; toggle_noeffect(PLAY, FALSE); send_cmd = CMD_PAUSE; rb_write(rb_gui2disk, &send_cmd, 1); } else { is_paused = 0; toggle_noeffect(PLAY, TRUE); send_cmd = CMD_RESUME; rb_write(rb_gui2disk, &send_cmd, 1); } try_waking_disk_thread(); return FALSE; } gint stop_event(GtkWidget * widget, GdkEvent * event, gpointer data) { char cmd; cue_t cue; is_file_loaded = 0; stop_after_current_song = 0; current_file[0] = '\0'; gtk_adjustment_set_value(GTK_ADJUSTMENT(adj_pos), 0.0f); zero_displays(); toggle_noeffect(PLAY, FALSE); if (!options.combine_play_pause) { toggle_noeffect(PAUSE, FALSE); } is_paused = 0; allow_seeks = 1; cmd = CMD_CUE; cue.filename = NULL; flush_rb_disk2gui(); rb_write(rb_gui2disk, &cmd, sizeof(char)); rb_write(rb_gui2disk, (void *)&cue, sizeof(cue_t)); try_waking_disk_thread(); show_scale_pos(TRUE); /* hide cover */ hide_cover_thumbnail(); if (embedded_picture != NULL) { free(embedded_picture); embedded_picture = NULL; embedded_picture_size = 0; } return FALSE; } /* called when a track ends without user intervention */ void decide_next_track(cue_t * pcue) { GtkTreePath * p; GtkTreeIter iter; playlist_t * pl; if ((pl = playlist_get_playing()) == NULL) { unprepare_playback(); return; } if (stop_after_current_song) { unprepare_playback(); return; } p = playlist_get_playing_path(pl); if (p != NULL) { /* there is a marked track in playlist */ if ((!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(shuffle_button))) && (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(repeat_button)))) { /* normal or list repeat mode */ gtk_tree_model_get_iter(GTK_TREE_MODEL(pl->store), &iter, p); gtk_tree_path_free(p); unmark_track(pl, &iter); if (choose_adjacent_track(pl->store, &iter)) { prepare_playback(pl, &iter, pcue); } else { if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(repeat_all_button))) { /* normal mode */ allow_seeks = 1; changed_pos(GTK_ADJUSTMENT(adj_pos), NULL); unprepare_playback(); } else { /* list repeat mode */ if (choose_first_track(pl->store, &iter)) { prepare_playback(pl, &iter, pcue); } else { allow_seeks = 1; changed_pos(GTK_ADJUSTMENT(adj_pos), NULL); unprepare_playback(); } } } } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(repeat_button))) { /* track repeat mode */ gtk_tree_model_get_iter(GTK_TREE_MODEL(pl->store), &iter, p); gtk_tree_path_free(p); prepare_playback(pl, &iter, pcue); } else { /* shuffle mode */ gtk_tree_model_get_iter(GTK_TREE_MODEL(pl->store), &iter, p); gtk_tree_path_free(p); unmark_track(pl, &iter); if (choose_random_track(pl->store, &iter)) { prepare_playback(pl, &iter, pcue); } else { unprepare_playback(); } } } else { /* no marked track in playlist */ if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(shuffle_button))) { /* normal or repeat mode */ if (choose_first_track(pl->store, &iter)) { prepare_playback(pl, &iter, pcue); } else { allow_seeks = 1; changed_pos(GTK_ADJUSTMENT(adj_pos), NULL); unprepare_playback(); } } else { /* shuffle mode */ if (choose_random_track(pl->store, &iter)) { prepare_playback(pl, &iter, pcue); } else { unprepare_playback(); } } } } /********************************************/ void swap_labels(int a, int b) { GtkWidget * tmp; int t; tmp = time_labels[options.time_idx[a]]; time_labels[options.time_idx[a]] = time_labels[options.time_idx[b]] ; time_labels[options.time_idx[b]] = tmp; t = options.time_idx[b]; options.time_idx[b] = options.time_idx[a]; options.time_idx[a] = t; } gint time_label0_clicked(GtkWidget * widget, GdkEventButton * event) { switch (event->button) { case 1: swap_labels(0, 1); refresh_time_displays(); break; case 3: swap_labels(0, 2); refresh_time_displays(); break; } return TRUE; } gint time_label1_clicked(GtkWidget * widget, GdkEventButton * event) { switch (event->button) { case 1: swap_labels(0, 1); refresh_time_displays(); break; case 3: swap_labels(1, 2); refresh_time_displays(); break; } return TRUE; } gint time_label2_clicked(GtkWidget * widget, GdkEventButton * event) { switch (event->button) { case 1: swap_labels(1, 2); refresh_time_displays(); break; case 3: swap_labels(0, 2); refresh_time_displays(); break; } return TRUE; } gint scroll_btn_pressed(GtkWidget * widget, GdkEventButton * event) { if (event->button != 1) return FALSE; x_scroll_start = event->x; x_scroll_pos = event->x; scroll_btn = event->button; return TRUE; } gint scroll_btn_released(GtkWidget * widget, GdkEventButton * event, gpointer * win) { scroll_btn = 0; gdk_window_set_cursor(gtk_widget_get_parent_window(GTK_WIDGET(win)), NULL); return TRUE; } gint scroll_motion_notify(GtkWidget * widget, GdkEventMotion * event, gpointer * win) { int dx = event->x - x_scroll_start; gboolean dummy; if (scroll_btn != 1) return FALSE; if (!scroll_btn) return TRUE; if (dx < -10) { #if (GTK_CHECK_VERSION(2,8,0)) GtkRange * range = GTK_RANGE(gtk_scrolled_window_get_hscrollbar(GTK_SCROLLED_WINDOW(win))); g_signal_emit_by_name(G_OBJECT(range), "move-slider", GTK_SCROLL_STEP_RIGHT, &dummy); #else g_signal_emit_by_name(G_OBJECT(win), "scroll-child", GTK_SCROLL_STEP_FORWARD, &dummy); #endif /* GTK_CHECK_VERSION */ x_scroll_start = event->x; gdk_window_set_cursor(gtk_widget_get_parent_window(GTK_WIDGET(win)), gdk_cursor_new(GDK_SB_H_DOUBLE_ARROW)); } if (dx > 10) { #if (GTK_CHECK_VERSION(2,8,0)) GtkRange * range = GTK_RANGE(gtk_scrolled_window_get_hscrollbar(GTK_SCROLLED_WINDOW(win))); g_signal_emit_by_name(G_OBJECT(range), "move-slider", GTK_SCROLL_STEP_LEFT, &dummy); #else g_signal_emit_by_name(G_OBJECT(win), "scroll-child", GTK_SCROLL_STEP_BACKWARD, &dummy); #endif /* GTK_CHECK_VERSION */ x_scroll_start = event->x; gdk_window_set_cursor(gtk_widget_get_parent_window(GTK_WIDGET(win)), gdk_cursor_new(GDK_SB_H_DOUBLE_ARROW)); } x_scroll_pos = event->x; return TRUE; } #ifdef HAVE_LOOP void hide_loop_bar() { gtk_widget_hide(loop_bar); main_window_resize(); } #endif /* HAVE_LOOP */ void repeat_toggled(GtkWidget * widget, gpointer data) { if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(repeat_button))) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(repeat_all_button), FALSE); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(shuffle_button), FALSE); options.repeat_on = 1; } else { options.repeat_on = 0; } #ifdef HAVE_LOOP if (options.repeat_on) { gtk_widget_show(loop_bar); } else { hide_loop_bar(); } #endif /* HAVE_LOOP */ } void repeat_all_toggled(GtkWidget * widget, gpointer data) { if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(repeat_all_button))) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(repeat_button), FALSE); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(shuffle_button), FALSE); options.repeat_all_on = 1; } else { options.repeat_all_on = 0; } } void shuffle_toggled(GtkWidget * widget, gpointer data) { if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(shuffle_button))) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(repeat_button), FALSE); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(repeat_all_button), FALSE); options.shuffle_on = 1; } else { options.shuffle_on = 0; } } void button_set_content(GtkWidget * button, char * imgpath, char * alt) { GdkPixbuf * pixbuf; GtkWidget * widget; if ((widget = gtk_bin_get_child(GTK_BIN(button))) != NULL) { gtk_widget_destroy(widget); } if ((pixbuf = gdk_pixbuf_new_from_file(imgpath, NULL)) != NULL) { widget = gtk_image_new_from_pixbuf(pixbuf); } else { widget = gtk_label_new(alt); } gtk_container_add(GTK_CONTAINER(button), widget); gtk_widget_show(widget); } void main_buttons_set_content(char * skin_path) { char path[MAXLEN]; sprintf(path, "%s/%s", skin_path, "prev.png"); button_set_content(prev_button, path, "prev"); sprintf(path, "%s/%s", skin_path, "stop.png"); button_set_content(stop_button, path, "stop"); sprintf(path, "%s/%s", skin_path, "next.png"); button_set_content(next_button, path, "next"); if (options.combine_play_pause) { sprintf(path, "%s/%s", skin_path, "play_pause.png"); button_set_content(play_button, path, "play/pause"); } else { sprintf(path, "%s/%s", skin_path, "play.png"); button_set_content(play_button, path, "play"); sprintf(path, "%s/%s", skin_path, "pause.png"); button_set_content(pause_button, path, "pause"); } sprintf(path, "%s/%s", skin_path, "repeat.png"); button_set_content(repeat_button, path, "repeat"); sprintf(path, "%s/%s", skin_path, "repeat_all.png"); button_set_content(repeat_all_button, path, "rep_all"); sprintf(path, "%s/%s", skin_path, "shuffle.png"); button_set_content(shuffle_button, path, "shuffle"); sprintf(path, "%s/%s", skin_path, "pl.png"); button_set_content(playlist_toggle, path, "PL"); sprintf(path, "%s/%s", skin_path, "ms.png"); button_set_content(musicstore_toggle, path, "MS"); sprintf(path, "%s/%s", skin_path, "fx.png"); button_set_content(plugin_toggle, path, "FX"); } #ifdef HAVE_JACK void jack_shutdown_window(void) { message_dialog(_("JACK connection lost"), main_window, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, NULL, _("JACK has either been shutdown or it " "disconnected Aqualung because it was " "not fast enough. All you can do now " "is restart both JACK and Aqualung.")); } #endif /* HAVE_JACK */ void set_win_title(void) { char str_session_id[32]; strcpy(win_title, "Aqualung"); if (aqualung_session_id > 0) { sprintf(str_session_id, ".%d", aqualung_session_id); strcat(win_title, str_session_id); } #ifdef HAVE_JACK if ((output == JACK_DRIVER) && (strcmp(client_name, "aqualung") != 0)) { strcat(win_title, " ["); strcat(win_title, client_name); strcat(win_title, "]"); } #endif /* HAVE_JACK */ } #ifdef HAVE_SYSTRAY void wm_systray_warn_cb(GtkWidget * widget, gpointer data) { set_option_from_toggle(widget, &options.wm_systray_warn); } void hide_all_windows(gpointer data) { if (wm_not_systray_capable) { main_window_closing(); return; } if (gtk_status_icon_is_embedded(systray_icon) == FALSE) { if (!wm_not_systray_capable && options.wm_systray_warn) { GtkWidget * check = gtk_check_button_new_with_label(_("Warn me if the Window Manager does not support system tray")); gtk_widget_set_name(check, "check_on_window"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), TRUE); g_signal_connect(G_OBJECT(check), "toggled", G_CALLBACK(wm_systray_warn_cb), NULL); message_dialog(_("Warning"), options.playlist_is_embedded ? main_window : playlist_window, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, check, _("Aqualung is compiled with system tray support, but " "the status icon could not be embedded in the notification " "area. Your desktop may not have support for a system tray, " "or it has not been configured correctly.")); wm_not_systray_capable = 1; } else { main_window_closing(); } return; } else { options.wm_systray_warn = 1; } if (!systray_main_window_on) { return; } systray_main_window_on = 0; save_window_position(); toplevel_window_foreach(TOP_WIN_TRAY, gtk_widget_hide); gtk_widget_hide(systray__hide); gtk_widget_show(systray__show); } void show_all_windows(gpointer data) { systray_main_window_on = 1; toplevel_window_foreach(TOP_WIN_TRAY, gtk_widget_show); restore_window_position(); gtk_widget_hide(systray__show); gtk_widget_show(systray__hide); } #endif /* HAVE_SYSTRAY */ gboolean cover_press_button_cb (GtkWidget *widget, GdkEventButton *event, gpointer user_data) { GtkTreePath * p; GtkTreeIter iter; playlist_t * pl; if ((pl = playlist_get_playing()) == NULL) { return FALSE; } if (event->type == GDK_BUTTON_PRESS && event->button == 1) { /* LMB ? */ p = playlist_get_playing_path(pl); if (p != NULL) { gtk_tree_model_get_iter(GTK_TREE_MODEL(pl->store), &iter, p); gtk_tree_path_free(p); if (is_file_loaded) { if (embedded_picture != NULL) { display_zoomed_cover_from_binary(main_window, c_event_box, embedded_picture, embedded_picture_size); } else { playlist_data_t * pldata; gtk_tree_model_get(GTK_TREE_MODEL(pl->store), &iter, PL_COL_DATA, &pldata, -1); display_zoomed_cover(main_window, c_event_box, pldata->file); } } } } return TRUE; } void main_window_set_font(int cond) { if (cond) { gtk_widget_modify_font(bigtimer_label, fd_bigtimer); gtk_widget_modify_font(smalltimer_label_1, fd_smalltimer); gtk_widget_modify_font(smalltimer_label_2, fd_smalltimer); gtk_widget_modify_font(label_title, fd_songtitle); gtk_widget_modify_font(label_mono, fd_songinfo); gtk_widget_modify_font(label_samplerate, fd_songinfo); gtk_widget_modify_font(label_bps, fd_songinfo); gtk_widget_modify_font(label_format, fd_songinfo); gtk_widget_modify_font(label_output, fd_songinfo); gtk_widget_modify_font(label_src_type, fd_songinfo); } } void create_main_window(char * skin_path) { GtkWidget * vbox; GtkWidget * disp_hbox; GtkWidget * btns_hbox; GtkWidget * title_hbox; GtkWidget * info_hbox; GtkWidget * vb_table; GtkWidget * conf__separator1; GtkWidget * conf__separator2; GtkWidget * time_table; GtkWidget * time0_viewp; GtkWidget * time1_viewp; GtkWidget * time2_viewp; GtkWidget * time_hbox1; GtkWidget * time_hbox2; GtkWidget * disp_vbox; GtkWidget * title_viewp; GtkWidget * title_scrolledwin; GtkWidget * info_viewp; GtkWidget * info_scrolledwin; GtkWidget * info_vsep; GtkWidget * sr_table; char path[MAXLEN]; set_win_title(); main_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_widget_set_name(main_window, "main_window"); register_toplevel_window(main_window, TOP_WIN_SKIN | TOP_WIN_TRAY); gtk_window_set_title(GTK_WINDOW(main_window), win_title); #ifdef HAVE_SYSTRAY if (systray_used) { aqualung_status_icon_set_tooltip_text(systray_icon, win_title); } #endif /* HAVE_SYSTRAY */ g_signal_connect(G_OBJECT(main_window), "event", G_CALLBACK(main_window_event), NULL); g_signal_connect(G_OBJECT(main_window), "key_press_event", G_CALLBACK(main_window_key_pressed), NULL); g_signal_connect(G_OBJECT(main_window), "key_release_event", G_CALLBACK(main_window_key_released), NULL); g_signal_connect(G_OBJECT(main_window), "button_press_event", G_CALLBACK(main_window_button_pressed), NULL); g_signal_connect(G_OBJECT(main_window), "focus_out_event", G_CALLBACK(main_window_focus_out), NULL); g_signal_connect(G_OBJECT(main_window), "window-state-event", G_CALLBACK(main_window_state_changed), NULL); gtk_widget_set_events(main_window, GDK_BUTTON_PRESS_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK); gtk_container_set_border_width(GTK_CONTAINER(main_window), 5); /* always on top ? */ if (options.main_window_always_on_top) { gtk_window_set_keep_above (GTK_WINDOW(main_window), TRUE); } /* initialize fonts */ fd_playlist = pango_font_description_from_string(options.playlist_font); fd_browser = pango_font_description_from_string(options.browser_font); fd_bigtimer = pango_font_description_from_string(options.bigtimer_font); fd_smalltimer = pango_font_description_from_string(options.smalltimer_font); fd_songtitle = pango_font_description_from_string(options.songtitle_font); fd_songinfo = pango_font_description_from_string(options.songinfo_font); fd_statusbar = pango_font_description_from_string(options.statusbar_font); aqualung_tooltips_init(); conf_menu = gtk_menu_new(); register_toplevel_window(conf_menu, TOP_WIN_SKIN); if (options.playlist_is_embedded) { init_plist_menu(conf_menu); plist_menu = conf_menu; } conf__options = gtk_menu_item_new_with_label(_("Settings")); conf__skin = gtk_menu_item_new_with_label(_("Skin chooser")); conf__jack = gtk_menu_item_new_with_label(_("JACK port setup")); if (!options.playlist_is_embedded) { conf__fileinfo = gtk_menu_item_new_with_label(_("File info")); } conf__separator1 = gtk_separator_menu_item_new(); conf__about = gtk_menu_item_new_with_label(_("About")); conf__separator2 = gtk_separator_menu_item_new(); conf__quit = gtk_menu_item_new_with_label(_("Quit")); if (options.playlist_is_embedded) { gtk_menu_shell_append(GTK_MENU_SHELL(conf_menu), conf__separator1); } gtk_menu_shell_append(GTK_MENU_SHELL(conf_menu), conf__options); gtk_menu_shell_append(GTK_MENU_SHELL(conf_menu), conf__skin); #ifdef HAVE_JACK if (output == JACK_DRIVER) { gtk_menu_shell_append(GTK_MENU_SHELL(conf_menu), conf__jack); } #endif /* HAVE_JACK */ if (!options.playlist_is_embedded) { gtk_menu_shell_append(GTK_MENU_SHELL(conf_menu), conf__fileinfo); gtk_menu_shell_append(GTK_MENU_SHELL(conf_menu), conf__separator1); } gtk_menu_shell_append(GTK_MENU_SHELL(conf_menu), conf__about); gtk_menu_shell_append(GTK_MENU_SHELL(conf_menu), conf__separator2); gtk_menu_shell_append(GTK_MENU_SHELL(conf_menu), conf__quit); g_signal_connect_swapped(G_OBJECT(conf__options), "activate", G_CALLBACK(conf__options_cb), NULL); g_signal_connect_swapped(G_OBJECT(conf__skin), "activate", G_CALLBACK(conf__skin_cb), NULL); g_signal_connect_swapped(G_OBJECT(conf__jack), "activate", G_CALLBACK(conf__jack_cb), NULL); g_signal_connect_swapped(G_OBJECT(conf__about), "activate", G_CALLBACK(conf__about_cb), NULL); g_signal_connect_swapped(G_OBJECT(conf__quit), "activate", G_CALLBACK(conf__quit_cb), NULL); if (!options.playlist_is_embedded) { g_signal_connect_swapped(G_OBJECT(conf__fileinfo), "activate", G_CALLBACK(conf__fileinfo_cb), NULL); gtk_widget_set_sensitive(conf__fileinfo, FALSE); gtk_widget_show(conf__fileinfo); } gtk_widget_show(conf__options); if (!options.disable_skin_support_settings) { gtk_widget_show(conf__skin); } gtk_widget_show(conf__jack); gtk_widget_show(conf__separator1); gtk_widget_show(conf__about); gtk_widget_show(conf__separator2); gtk_widget_show(conf__quit); vbox = gtk_vbox_new(FALSE, 0); gtk_container_add(GTK_CONTAINER(main_window), vbox); disp_hbox = gtk_hbox_new(FALSE, 3); gtk_box_pack_start(GTK_BOX(vbox), disp_hbox, FALSE, FALSE, 0); time_table = gtk_table_new(2, 2, FALSE); disp_vbox = gtk_vbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(disp_hbox), time_table, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(disp_hbox), disp_vbox, TRUE, TRUE, 0); time0_viewp = gtk_viewport_new(NULL, NULL); time1_viewp = gtk_viewport_new(NULL, NULL); time2_viewp = gtk_viewport_new(NULL, NULL); gtk_widget_set_name(time0_viewp, "time_viewport"); gtk_widget_set_name(time1_viewp, "time_viewport"); gtk_widget_set_name(time2_viewp, "time_viewport"); g_signal_connect(G_OBJECT(time0_viewp), "button_press_event", G_CALLBACK(time_label0_clicked), NULL); g_signal_connect(G_OBJECT(time1_viewp), "button_press_event", G_CALLBACK(time_label1_clicked), NULL); g_signal_connect(G_OBJECT(time2_viewp), "button_press_event", G_CALLBACK(time_label2_clicked), NULL); gtk_table_attach(GTK_TABLE(time_table), time0_viewp, 0, 2, 0, 1, GTK_FILL | GTK_EXPAND, 0, 0, 0); gtk_table_attach(GTK_TABLE(time_table), time1_viewp, 0, 1, 1, 2, GTK_FILL | GTK_EXPAND, 0, 0, 0); gtk_table_attach(GTK_TABLE(time_table), time2_viewp, 1, 2, 1, 2, GTK_FILL | GTK_EXPAND, 0, 0, 0); info_scrolledwin = gtk_scrolled_window_new(NULL, NULL); gtk_widget_set_size_request(info_scrolledwin, 1, -1); /* MAGIC */ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(info_scrolledwin), GTK_POLICY_NEVER, GTK_POLICY_NEVER); info_viewp = gtk_viewport_new(NULL, NULL); gtk_widget_set_name(info_viewp, "info_viewport"); gtk_container_add(GTK_CONTAINER(info_scrolledwin), info_viewp); gtk_widget_set_events(info_viewp, GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK); g_signal_connect(G_OBJECT(info_viewp), "button_press_event", G_CALLBACK(scroll_btn_pressed), NULL); g_signal_connect(G_OBJECT(info_viewp), "button_release_event", G_CALLBACK(scroll_btn_released), (gpointer)info_scrolledwin); g_signal_connect(G_OBJECT(info_viewp), "motion_notify_event", G_CALLBACK(scroll_motion_notify), (gpointer)info_scrolledwin); info_hbox = gtk_hbox_new(FALSE, 0); gtk_container_set_border_width(GTK_CONTAINER(info_hbox), 1); gtk_container_add(GTK_CONTAINER(info_viewp), info_hbox); title_scrolledwin = gtk_scrolled_window_new(NULL, NULL); gtk_widget_set_size_request(title_scrolledwin, 1, -1); /* MAGIC */ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(title_scrolledwin), GTK_POLICY_NEVER, GTK_POLICY_NEVER); title_viewp = gtk_viewport_new(NULL, NULL); gtk_widget_set_name(title_viewp, "title_viewport"); gtk_container_add(GTK_CONTAINER(title_scrolledwin), title_viewp); gtk_widget_set_events(title_viewp, GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK); g_signal_connect(G_OBJECT(title_viewp), "button_press_event", G_CALLBACK(scroll_btn_pressed), NULL); g_signal_connect(G_OBJECT(title_viewp), "button_release_event", G_CALLBACK(scroll_btn_released), (gpointer)title_scrolledwin); g_signal_connect(G_OBJECT(title_viewp), "motion_notify_event", G_CALLBACK(scroll_motion_notify), (gpointer)title_scrolledwin); title_hbox = gtk_hbox_new(FALSE, 0); gtk_container_set_border_width(GTK_CONTAINER(title_hbox), 1); gtk_container_add(GTK_CONTAINER(title_viewp), title_hbox); gtk_box_pack_start(GTK_BOX(disp_vbox), title_scrolledwin, TRUE, FALSE, 0); gtk_box_pack_start(GTK_BOX(disp_vbox), info_scrolledwin, TRUE, FALSE, 0); /* labels */ bigtimer_label = time_labels[options.time_idx[0]] = gtk_label_new(""); gtk_widget_set_name(time_labels[options.time_idx[0]], "big_timer_label"); gtk_container_add(GTK_CONTAINER(time0_viewp), time_labels[options.time_idx[0]]); time_hbox1 = gtk_hbox_new(FALSE, 3); gtk_container_set_border_width(GTK_CONTAINER(time_hbox1), 2); gtk_container_add(GTK_CONTAINER(time1_viewp), time_hbox1); smalltimer_label_1 = time_labels[options.time_idx[1]] = gtk_label_new(""); gtk_widget_set_name(time_labels[options.time_idx[1]], "small_timer_label"); gtk_box_pack_start(GTK_BOX(time_hbox1), time_labels[options.time_idx[1]], TRUE, TRUE, 0); time_hbox2 = gtk_hbox_new(FALSE, 3); gtk_container_set_border_width(GTK_CONTAINER(time_hbox2), 2); gtk_container_add(GTK_CONTAINER(time2_viewp), time_hbox2); smalltimer_label_2 = time_labels[options.time_idx[2]] = gtk_label_new(""); gtk_widget_set_name(time_labels[options.time_idx[2]], "small_timer_label"); gtk_box_pack_start(GTK_BOX(time_hbox2), time_labels[options.time_idx[2]], TRUE, TRUE, 0); label_title = gtk_label_new(""); gtk_widget_set_name(label_title, "label_title"); gtk_box_pack_start(GTK_BOX(title_hbox), label_title, FALSE, FALSE, 3); label_mono = gtk_label_new(""); gtk_box_pack_start(GTK_BOX(info_hbox), label_mono, FALSE, FALSE, 3); gtk_widget_set_name(label_mono, "label_info"); label_samplerate = gtk_label_new("0"); gtk_widget_set_name(label_samplerate, "label_info"); gtk_box_pack_start(GTK_BOX(info_hbox), label_samplerate, FALSE, FALSE, 3); label_bps = gtk_label_new(""); gtk_widget_set_name(label_bps, "label_info"); gtk_box_pack_start(GTK_BOX(info_hbox), label_bps, FALSE, FALSE, 3); label_format = gtk_label_new(""); gtk_widget_set_name(label_format, "label_info"); gtk_box_pack_start(GTK_BOX(info_hbox), label_format, FALSE, FALSE, 3); info_vsep = gtk_vseparator_new(); gtk_box_pack_start(GTK_BOX(info_hbox), info_vsep, FALSE, FALSE, 3); label_output = gtk_label_new(""); gtk_widget_set_name(label_output, "label_info"); gtk_box_pack_start(GTK_BOX(info_hbox), label_output, FALSE, FALSE, 3); label_src_type = gtk_label_new(""); gtk_widget_set_name(label_src_type, "label_info"); gtk_box_pack_start(GTK_BOX(info_hbox), label_src_type, FALSE, FALSE, 3); main_window_set_font(options.override_skin_settings); /* Volume and balance slider */ vb_table = gtk_table_new(1, 3, FALSE); gtk_table_set_col_spacings(GTK_TABLE(vb_table), 3); gtk_box_pack_start(GTK_BOX(disp_vbox), vb_table, TRUE, FALSE, 0); adj_vol = gtk_adjustment_new(0.0f, -41.0f, 6.0f, 1.0f, 3.0f, 0.0f); g_signal_connect(G_OBJECT(adj_vol), "value_changed", G_CALLBACK(changed_vol), NULL); scale_vol = gtk_hscale_new(GTK_ADJUSTMENT(adj_vol)); gtk_widget_set_name(scale_vol, "scale_vol"); g_signal_connect(GTK_OBJECT(scale_vol), "button_press_event", (GtkSignalFunc)scale_vol_button_press_event, NULL); g_signal_connect(GTK_OBJECT(scale_vol), "button_release_event", (GtkSignalFunc)scale_vol_button_release_event, NULL); gtk_widget_set_size_request(scale_vol, -1, 8); gtk_scale_set_digits(GTK_SCALE(scale_vol), 0); gtk_scale_set_draw_value(GTK_SCALE(scale_vol), FALSE); gtk_table_attach(GTK_TABLE(vb_table), scale_vol, 0, 2, 0, 1, GTK_FILL | GTK_EXPAND, 0, 0, 0); adj_bal = gtk_adjustment_new(0.0f, -100.0f, 100.0f, 1.0f, 10.0f, 0.0f); g_signal_connect(G_OBJECT(adj_bal), "value_changed", G_CALLBACK(changed_bal), NULL); scale_bal = gtk_hscale_new(GTK_ADJUSTMENT(adj_bal)); gtk_scale_set_digits(GTK_SCALE(scale_bal), 0); gtk_widget_set_size_request(scale_bal, -1, 8); gtk_widget_set_name(scale_bal, "scale_bal"); g_signal_connect(GTK_OBJECT(scale_bal), "button_press_event", (GtkSignalFunc)scale_bal_button_press_event, NULL); g_signal_connect(GTK_OBJECT(scale_bal), "button_release_event", (GtkSignalFunc)scale_bal_button_release_event, NULL); gtk_scale_set_draw_value(GTK_SCALE(scale_bal), FALSE); gtk_table_attach(GTK_TABLE(vb_table), scale_bal, 2, 3, 0, 1, GTK_FILL | GTK_EXPAND, 0, 0, 0); /* Loop bar */ #ifdef HAVE_LOOP loop_bar = aqualung_loop_bar_new(options.loop_range_start, options.loop_range_end); g_signal_connect(loop_bar, "range-changed", G_CALLBACK(loop_range_changed_cb), NULL); gtk_widget_set_size_request(loop_bar, -1, 14); gtk_box_pack_start(GTK_BOX(vbox), loop_bar, FALSE, FALSE, 3); #endif /* HAVE_LOOP */ /* Position slider */ adj_pos = gtk_adjustment_new(0, 0, 100, 1, 5, 0); g_signal_connect(G_OBJECT(adj_pos), "value_changed", G_CALLBACK(changed_pos), NULL); scale_pos = gtk_hscale_new(GTK_ADJUSTMENT(adj_pos)); gtk_widget_set_name(scale_pos, "scale_pos"); g_signal_connect(GTK_OBJECT(scale_pos), "button_press_event", (GtkSignalFunc)scale_button_press_event, NULL); g_signal_connect(GTK_OBJECT(scale_pos), "button_release_event", (GtkSignalFunc)scale_button_release_event, NULL); gtk_scale_set_digits(GTK_SCALE(scale_pos), 0); gtk_scale_set_draw_value(GTK_SCALE(scale_pos), FALSE); gtk_range_set_update_policy(GTK_RANGE(scale_pos), GTK_UPDATE_DISCONTINUOUS); gtk_box_pack_start(GTK_BOX(vbox), scale_pos, FALSE, FALSE, 3); vbox_sep = gtk_vbox_new (FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox), vbox_sep, FALSE, FALSE, 2); GTK_WIDGET_UNSET_FLAGS(scale_vol, GTK_CAN_FOCUS); GTK_WIDGET_UNSET_FLAGS(scale_bal, GTK_CAN_FOCUS); GTK_WIDGET_UNSET_FLAGS(scale_pos, GTK_CAN_FOCUS); /* cover display widget */ cover_align = gtk_alignment_new(0.5f, 0.5f, 0.0f, 0.0f); gtk_box_pack_start(GTK_BOX(disp_hbox), cover_align, FALSE, FALSE, 0); cover_image_area = gtk_image_new(); c_event_box = gtk_event_box_new(); gtk_container_add(GTK_CONTAINER(cover_align), c_event_box); gtk_container_add(GTK_CONTAINER(c_event_box), cover_image_area); g_signal_connect(G_OBJECT(c_event_box), "button_press_event", G_CALLBACK(cover_press_button_cb), cover_image_area); /* Embedded playlist */ if (options.playlist_is_embedded && options.buttons_at_the_bottom) { playlist_window = gtk_vbox_new(FALSE, 0); gtk_widget_set_name(playlist_window, "playlist_window"); gtk_box_pack_start(GTK_BOX(vbox), playlist_window, TRUE, TRUE, 3); } /* Button box with prev, play, pause, stop, next buttons */ btns_hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox), btns_hbox, FALSE, FALSE, 0); prev_button = gtk_button_new(); aqualung_widget_set_tooltip_text(prev_button, _("Previous song")); stop_button = gtk_button_new(); aqualung_widget_set_tooltip_text(stop_button, _("Stop")); next_button = gtk_button_new(); aqualung_widget_set_tooltip_text(next_button, _("Next song")); play_button = gtk_toggle_button_new(); if (options.combine_play_pause) { aqualung_widget_set_tooltip_text(play_button, _("Play/Pause")); } else { aqualung_widget_set_tooltip_text(play_button, _("Play")); pause_button = gtk_toggle_button_new(); aqualung_widget_set_tooltip_text(pause_button, _("Pause")); } GTK_WIDGET_UNSET_FLAGS(prev_button, GTK_CAN_FOCUS); GTK_WIDGET_UNSET_FLAGS(stop_button, GTK_CAN_FOCUS); GTK_WIDGET_UNSET_FLAGS(next_button, GTK_CAN_FOCUS); GTK_WIDGET_UNSET_FLAGS(play_button, GTK_CAN_FOCUS); if (!options.combine_play_pause) { GTK_WIDGET_UNSET_FLAGS(pause_button, GTK_CAN_FOCUS); } gtk_box_pack_start(GTK_BOX(btns_hbox), prev_button, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(btns_hbox), play_button, FALSE, FALSE, 0); if (!options.combine_play_pause) { gtk_box_pack_start(GTK_BOX(btns_hbox), pause_button, FALSE, FALSE, 0); } gtk_box_pack_start(GTK_BOX(btns_hbox), stop_button, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(btns_hbox), next_button, FALSE, FALSE, 0); g_signal_connect(prev_button, "clicked", G_CALLBACK(prev_event), NULL); play_id = g_signal_connect(play_button, "toggled", G_CALLBACK(play_event), NULL); if (!options.combine_play_pause) { pause_id = g_signal_connect(pause_button, "toggled", G_CALLBACK(pause_event), NULL); } g_signal_connect(stop_button, "clicked", G_CALLBACK(stop_event), NULL); g_signal_connect(next_button, "clicked", G_CALLBACK(next_event), NULL); /* toggle buttons for shuffle and repeat */ sr_table = gtk_table_new(2, 2, FALSE); repeat_button = gtk_toggle_button_new(); aqualung_widget_set_tooltip_text(repeat_button, _("Repeat current song")); gtk_widget_set_size_request(repeat_button, -1, 1); gtk_table_attach(GTK_TABLE(sr_table), repeat_button, 0, 1, 0, 1, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 0, 0); g_signal_connect(repeat_button, "toggled", G_CALLBACK(repeat_toggled), NULL); repeat_all_button = gtk_toggle_button_new(); aqualung_widget_set_tooltip_text(repeat_all_button, _("Repeat all songs")); gtk_widget_set_size_request(repeat_all_button, -1, 1); gtk_table_attach(GTK_TABLE(sr_table), repeat_all_button, 0, 1, 1, 2, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 0, 0); g_signal_connect(repeat_all_button, "toggled", G_CALLBACK(repeat_all_toggled), NULL); shuffle_button = gtk_toggle_button_new(); aqualung_widget_set_tooltip_text(shuffle_button, _("Shuffle songs")); gtk_widget_set_size_request(shuffle_button, -1, 1); gtk_table_attach(GTK_TABLE(sr_table), shuffle_button, 1, 2, 0, 2, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 0, 0); g_signal_connect(shuffle_button, "toggled", G_CALLBACK(shuffle_toggled), NULL); GTK_WIDGET_UNSET_FLAGS(repeat_button, GTK_CAN_FOCUS); GTK_WIDGET_UNSET_FLAGS(repeat_all_button, GTK_CAN_FOCUS); GTK_WIDGET_UNSET_FLAGS(shuffle_button, GTK_CAN_FOCUS); /* toggle buttons for sub-windows visibility */ playlist_toggle = gtk_toggle_button_new(); aqualung_widget_set_tooltip_text(playlist_toggle, _("Toggle playlist")); gtk_box_pack_end(GTK_BOX(btns_hbox), playlist_toggle, FALSE, FALSE, 0); musicstore_toggle = gtk_toggle_button_new(); aqualung_widget_set_tooltip_text(musicstore_toggle, _("Toggle music store")); gtk_box_pack_end(GTK_BOX(btns_hbox), musicstore_toggle, FALSE, FALSE, 3); plugin_toggle = gtk_toggle_button_new(); aqualung_widget_set_tooltip_text(plugin_toggle, _("Toggle LADSPA patch builder")); #ifdef HAVE_LADSPA gtk_box_pack_end(GTK_BOX(btns_hbox), plugin_toggle, FALSE, FALSE, 0); #endif /* HAVE_LADSPA */ g_signal_connect(playlist_toggle, "toggled", G_CALLBACK(playlist_toggled), NULL); g_signal_connect(musicstore_toggle, "toggled", G_CALLBACK(musicstore_toggled), NULL); g_signal_connect(plugin_toggle, "toggled", G_CALLBACK(plugin_toggled), NULL); GTK_WIDGET_UNSET_FLAGS(playlist_toggle, GTK_CAN_FOCUS); GTK_WIDGET_UNSET_FLAGS(musicstore_toggle, GTK_CAN_FOCUS); GTK_WIDGET_UNSET_FLAGS(plugin_toggle, GTK_CAN_FOCUS); gtk_box_pack_end(GTK_BOX(btns_hbox), sr_table, FALSE, FALSE, 3); if (options.disable_skin_support_settings) { sprintf(path, "%s/no_skin", AQUALUNG_SKINDIR); main_buttons_set_content(path); } else { main_buttons_set_content(skin_path); } set_buttons_relief(); /* Embedded playlist */ if (options.playlist_is_embedded && !options.buttons_at_the_bottom) { playlist_window = gtk_vbox_new(FALSE, 0); gtk_widget_set_name(playlist_window, "playlist_window"); gtk_box_pack_start(GTK_BOX(vbox), playlist_window, TRUE, TRUE, 3); } aqualung_tooltips_set_enabled(options.enable_tooltips); } void process_filenames(GSList * list, int enqueue, int start_playback, int has_tab, char * tab_name) { int mode; char * name = NULL; if (!has_tab) { if (enqueue) { mode = PLAYLIST_ENQUEUE; } else { mode = PLAYLIST_LOAD; } } else { if (strlen(tab_name) == 0) { mode = PLAYLIST_LOAD_TAB; } else { if (g_utf8_validate(tab_name, -1, NULL)) { name = g_strdup(tab_name); } else { name = g_locale_to_utf8(tab_name, -1, NULL, NULL, NULL); } if (name == NULL) { fprintf(stderr, "process_filenames(): unable to convert tab name to UTF-8\n"); } if (enqueue) { mode = PLAYLIST_ENQUEUE; } else { mode = PLAYLIST_LOAD; } } } playlist_load(list, mode, name, start_playback); if (name != NULL) { g_free(name); } } /*** Systray support ***/ #ifdef HAVE_SYSTRAY void systray_popup_menu_cb(GtkStatusIcon * systray_icon, guint button, guint time, gpointer data) { if (get_systray_semaphore() == 0) { gtk_menu_popup(GTK_MENU(systray_menu), NULL, NULL, gtk_status_icon_position_menu, data, button, time); } } void systray__show_cb(gpointer data) { show_all_windows(NULL); } void systray__hide_cb(gpointer data) { hide_all_windows(NULL); } void systray__play_cb(gpointer data) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(play_button), !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(play_button))); } void systray__pause_cb(gpointer data) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pause_button), !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(pause_button))); } void systray__stop_cb(gpointer data) { stop_event(NULL, NULL, NULL); } void systray__prev_cb(gpointer data) { prev_event(NULL, NULL, NULL); } void systray__next_cb(gpointer data) { next_event(NULL, NULL, NULL); } void systray__quit_cb(gpointer data) { main_window_closing(); } void systray_activate_cb(GtkStatusIcon * systray_icon, gpointer data) { if (get_systray_semaphore() == 0) { if (!systray_main_window_on) { systray__show_cb(NULL); } else { systray__hide_cb(NULL); } } } #if (GTK_CHECK_VERSION(2,15,0)) gboolean systray_mouse_wheel(int mouse_wheel_option, gboolean vertical_wheel, guint32 time_since_last_event, GtkScrollType scroll_type) { GtkScrollType reverse_direction(GtkScrollType scroll_type) { switch (scroll_type) { case GTK_SCROLL_STEP_BACKWARD: return GTK_SCROLL_STEP_FORWARD; case GTK_SCROLL_STEP_FORWARD: return GTK_SCROLL_STEP_BACKWARD; default: return scroll_type; } } switch (mouse_wheel_option) { case SYSTRAY_MW_CMD_VOLUME: if (time_since_last_event > 100) { if (vertical_wheel) scroll_type = reverse_direction(scroll_type); change_volume_or_balance(scale_vol, scroll_type); return TRUE; } break; case SYSTRAY_MW_CMD_BALANCE: if (time_since_last_event > 100) { if (vertical_wheel) scroll_type = reverse_direction(scroll_type); change_volume_or_balance(scale_bal, scroll_type); return TRUE; } break; case SYSTRAY_MW_CMD_SONG_POSITION: move_song_position_slider(scroll_type); seek_song(); return TRUE; case SYSTRAY_MW_CMD_NEXT_PREV_SONG: // At most one per second. if (time_since_last_event > 1000) { if (scroll_type == GTK_SCROLL_STEP_BACKWARD) { prev_event(NULL, NULL, NULL); return TRUE; } else if (scroll_type == GTK_SCROLL_STEP_FORWARD) { next_event(NULL, NULL, NULL); return TRUE; } } break; } return FALSE; } gboolean systray_scroll_event_cb(GtkStatusIcon * systray_icon, GdkEventScroll * event, gpointer user_data) { gboolean result = FALSE; guint32 time_since_last_event; if (!options.use_systray) return FALSE; time_since_last_event = event->time - last_systray_scroll_event_time; switch (event->direction) { case GDK_SCROLL_LEFT: result = systray_mouse_wheel(options.systray_mouse_wheel_horizontal, FALSE, time_since_last_event, GTK_SCROLL_STEP_BACKWARD); break; case GDK_SCROLL_RIGHT: result = systray_mouse_wheel(options.systray_mouse_wheel_horizontal, FALSE, time_since_last_event, GTK_SCROLL_STEP_FORWARD); break; case GDK_SCROLL_UP: result = systray_mouse_wheel(options.systray_mouse_wheel_vertical, TRUE, time_since_last_event, GTK_SCROLL_STEP_BACKWARD); break; case GDK_SCROLL_DOWN: result = systray_mouse_wheel(options.systray_mouse_wheel_vertical, TRUE, time_since_last_event, GTK_SCROLL_STEP_FORWARD); break; } if (result) { last_systray_scroll_event_time = event->time; } return result; } gboolean systray_mouse_button(int mouse_button_option) { switch (mouse_button_option) { case SYSTRAY_MB_CMD_PLAY_STOP_SONG: if (is_file_loaded) { systray__stop_cb(NULL); } else { systray__play_cb(NULL); } return TRUE; case SYSTRAY_MB_CMD_PLAY_PAUSE_SONG: if (is_file_loaded && !options.combine_play_pause) { systray__pause_cb(NULL); } else { systray__play_cb(NULL); } return TRUE; case SYSTRAY_MB_CMD_PREV_SONG: systray__prev_cb(NULL); return TRUE; case SYSTRAY_MB_CMD_NEXT_SONG: systray__next_cb(NULL); return TRUE; } return FALSE; } gboolean systray_button_press_event_cb(GtkStatusIcon * systray_icon, GdkEventButton * event, gpointer user_data) { int i; if (!options.use_systray) return FALSE; if (event->type == GDK_BUTTON_PRESS) { for (i = 0; i < options.systray_mouse_buttons_count; i++) { if (options.systray_mouse_buttons[i].button_nr == event->button) { return systray_mouse_button(options.systray_mouse_buttons[i].command); } } } return FALSE; } #endif /* GTK_CHECK_VERSION */ /* returns a hbox with a stock image and label in it */ GtkWidget * create_systray_menu_item(const gchar * stock_id, char * text) { GtkWidget * hbox; GtkWidget * widget; hbox = gtk_hbox_new(FALSE, 5); gtk_widget_show(hbox); widget = gtk_image_new_from_stock(stock_id, GTK_ICON_SIZE_MENU); gtk_widget_show(widget); gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, TRUE, 2); widget = gtk_label_new(text); gtk_widget_show(widget); gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, TRUE, 2); return hbox; } void setup_systray(void) { char path[MAXLEN]; GtkWidget * systray__separator1; GtkWidget * systray__separator2; sprintf(path, "%s/icon_64.png", AQUALUNG_DATADIR); systray_icon = gtk_status_icon_new_from_file(path); g_signal_connect_swapped(G_OBJECT(systray_icon), "activate", G_CALLBACK(systray_activate_cb), NULL); g_signal_connect_swapped(G_OBJECT(systray_icon), "popup-menu", G_CALLBACK(systray_popup_menu_cb), (gpointer)systray_icon); #if (GTK_CHECK_VERSION(2,15,0)) g_signal_connect(G_OBJECT(systray_icon), "scroll-event", G_CALLBACK(systray_scroll_event_cb), NULL); g_signal_connect(G_OBJECT(systray_icon), "button-press-event", G_CALLBACK(systray_button_press_event_cb), NULL); #endif systray_menu = gtk_menu_new(); register_toplevel_window(systray_menu, TOP_WIN_SKIN); systray__show = gtk_menu_item_new_with_label(_("Show Aqualung")); systray__hide = gtk_menu_item_new_with_label(_("Hide Aqualung")); systray__separator1 = gtk_separator_menu_item_new(); systray__play = gtk_menu_item_new(); gtk_container_add(GTK_CONTAINER(systray__play), create_systray_menu_item(GTK_STOCK_MEDIA_PLAY, options.combine_play_pause ? _("Play/Pause") : _("Play"))); if (!options.combine_play_pause) { systray__pause = gtk_menu_item_new(); gtk_container_add(GTK_CONTAINER(systray__pause), create_systray_menu_item(GTK_STOCK_MEDIA_PAUSE, _("Pause"))); } systray__stop = gtk_menu_item_new(); gtk_container_add(GTK_CONTAINER(systray__stop), create_systray_menu_item(GTK_STOCK_MEDIA_STOP, _("Stop"))); systray__prev = gtk_menu_item_new(); gtk_container_add(GTK_CONTAINER(systray__prev), create_systray_menu_item(GTK_STOCK_MEDIA_PREVIOUS, _("Previous"))); systray__next = gtk_menu_item_new(); gtk_container_add(GTK_CONTAINER(systray__next), create_systray_menu_item(GTK_STOCK_MEDIA_NEXT, _("Next"))); systray__separator2 = gtk_separator_menu_item_new(); systray__quit = gtk_menu_item_new(); gtk_container_add(GTK_CONTAINER(systray__quit), create_systray_menu_item(GTK_STOCK_STOP, _("Quit"))); gtk_menu_shell_append(GTK_MENU_SHELL(systray_menu), systray__show); gtk_menu_shell_append(GTK_MENU_SHELL(systray_menu), systray__hide); gtk_menu_shell_append(GTK_MENU_SHELL(systray_menu), systray__separator1); gtk_menu_shell_append(GTK_MENU_SHELL(systray_menu), systray__play); if (!options.combine_play_pause) { gtk_menu_shell_append(GTK_MENU_SHELL(systray_menu), systray__pause); } gtk_menu_shell_append(GTK_MENU_SHELL(systray_menu), systray__stop); gtk_menu_shell_append(GTK_MENU_SHELL(systray_menu), systray__prev); gtk_menu_shell_append(GTK_MENU_SHELL(systray_menu), systray__next); gtk_menu_shell_append(GTK_MENU_SHELL(systray_menu), systray__separator2); gtk_menu_shell_append(GTK_MENU_SHELL(systray_menu), systray__quit); g_signal_connect_swapped(G_OBJECT(systray__show), "activate", G_CALLBACK(systray__show_cb), NULL); g_signal_connect_swapped(G_OBJECT(systray__hide), "activate", G_CALLBACK(systray__hide_cb), NULL); g_signal_connect_swapped(G_OBJECT(systray__play), "activate", G_CALLBACK(systray__play_cb), NULL); if (!options.combine_play_pause) { g_signal_connect_swapped(G_OBJECT(systray__pause), "activate", G_CALLBACK(systray__pause_cb), NULL); } g_signal_connect_swapped(G_OBJECT(systray__stop), "activate", G_CALLBACK(systray__stop_cb), NULL); g_signal_connect_swapped(G_OBJECT(systray__prev), "activate", G_CALLBACK(systray__prev_cb), NULL); g_signal_connect_swapped(G_OBJECT(systray__next), "activate", G_CALLBACK(systray__next_cb), NULL); g_signal_connect_swapped(G_OBJECT(systray__quit), "activate", G_CALLBACK(systray__quit_cb), NULL); gtk_widget_show(systray_menu); gtk_widget_show(systray__hide); gtk_widget_show(systray__separator1); gtk_widget_show(systray__play); if (!options.combine_play_pause) { gtk_widget_show(systray__pause); } gtk_widget_show(systray__stop); gtk_widget_show(systray__prev); gtk_widget_show(systray__next); gtk_widget_show(systray__separator2); gtk_widget_show(systray__quit); } #endif /* HAVE_SYSTRAY */ void create_gui(int argc, char ** argv, int optind, int enqueue, unsigned long rate, unsigned long rb_audio_size) { char path[MAXLEN]; GList * glist = NULL; GdkPixbuf * pixbuf = NULL; srand(time(0)); sample_pos = 0; out_SR = rate; rb_size = rb_audio_size; gdk_threads_enter(); gtk_init(&argc, &argv); #ifdef HAVE_LADSPA lrdf_init(); #endif /* HAVE_LADSPA */ if (chdir(options.confdir) != 0) { if (errno == ENOENT) { fprintf(stderr, "Creating directory %s\n", options.confdir); mkdir(options.confdir, S_IRUSR | S_IWUSR | S_IXUSR); chdir(options.confdir); } else { fprintf(stderr, "An error occured while attempting chdir(\"%s\"). errno = %d\n", options.confdir, errno); } } load_config(); if (options.title_format[0] == '\0') sprintf(options.title_format, "%%a: %%t [%%r]"); if (options.skin[0] == '\0') { sprintf(options.skin, "%s/plain", AQUALUNG_SKINDIR); options.main_pos_x = 280; options.main_pos_y = 30; options.main_size_x = 380; options.main_size_y = 380; options.browser_pos_x = 30; options.browser_pos_y = 30; options.browser_size_x = 240; options.browser_size_y = 380; options.browser_on = 1; options.playlist_pos_x = 300; options.playlist_pos_y = 180; options.playlist_size_x = 400; options.playlist_size_y = 500; options.playlist_on = 1; } if (options.cddb_server[0] == '\0') { sprintf(options.cddb_server, "freedb.org"); } if (options.src_type == -1) { options.src_type = 4; } if (options.disable_skin_support_settings) { sprintf(path, "%s/no_skin/rc", AQUALUNG_SKINDIR); } else { sprintf(path, "%s/rc", options.skin); } gtk_rc_parse(path); #ifdef HAVE_SYSTRAY if (options.use_systray) { systray_used = 1; setup_systray(); } #endif /* HAVE_SYSTRAY */ create_main_window(options.skin); vol_prev = -101.0f; gtk_adjustment_set_value(GTK_ADJUSTMENT(adj_vol), options.vol); bal_prev = -101.0f; gtk_adjustment_set_value(GTK_ADJUSTMENT(adj_bal), options.bal); create_playlist(); playlist_auto_save_reset(); create_music_browser(); #ifdef HAVE_LADSPA create_fxbuilder(); load_plugin_data(); #endif /* HAVE_LADSPA */ #ifdef HAVE_CDDA create_cdda_node(); cdda_scanner_start(); #endif /* HAVE_CDDA */ #ifdef HAVE_PODCAST create_podcast_node(); store_podcast_load(); store_podcast_updater_start(); #endif /* HAVE_PODCAST */ music_store_load_all(); options_store_watcher_start(); sprintf(path, "%s/icon_16.png", AQUALUNG_DATADIR); if ((pixbuf = gdk_pixbuf_new_from_file(path, NULL)) != NULL) { glist = g_list_append(glist, gdk_pixbuf_new_from_file(path, NULL)); } sprintf(path, "%s/icon_24.png", AQUALUNG_DATADIR); if ((pixbuf = gdk_pixbuf_new_from_file(path, NULL)) != NULL) { glist = g_list_append(glist, gdk_pixbuf_new_from_file(path, NULL)); } sprintf(path, "%s/icon_32.png", AQUALUNG_DATADIR); if ((pixbuf = gdk_pixbuf_new_from_file(path, NULL)) != NULL) { glist = g_list_append(glist, gdk_pixbuf_new_from_file(path, NULL)); } sprintf(path, "%s/icon_48.png", AQUALUNG_DATADIR); if ((pixbuf = gdk_pixbuf_new_from_file(path, NULL)) != NULL) { glist = g_list_append(glist, gdk_pixbuf_new_from_file(path, NULL)); } sprintf(path, "%s/icon_64.png", AQUALUNG_DATADIR); if ((pixbuf = gdk_pixbuf_new_from_file(path, NULL)) != NULL) { glist = g_list_append(glist, gdk_pixbuf_new_from_file(path, NULL)); } if (glist != NULL) { gtk_window_set_default_icon_list(glist); g_list_free(glist); } if (options.repeat_on) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(repeat_button), TRUE); } if (options.repeat_all_on) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(repeat_all_button), TRUE); } if (options.shuffle_on) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(shuffle_button), TRUE); } if (playlist_state != -1) { options.playlist_on = playlist_state; } if (browser_state != -1) { options.browser_on = browser_state; } if (options.browser_on) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(musicstore_toggle), TRUE); } if (options.playlist_on) { if (options.playlist_is_embedded) { g_signal_handlers_block_by_func(G_OBJECT(playlist_toggle), playlist_toggled, NULL); } gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(playlist_toggle), TRUE); if (options.playlist_is_embedded) { g_signal_handlers_unblock_by_func(G_OBJECT(playlist_toggle), playlist_toggled, NULL); } } restore_window_position(); gtk_widget_show_all(main_window); #ifdef HAVE_SYSTRAY if (options.use_systray && options.systray_start_minimized) { toplevel_window_foreach(TOP_WIN_TRAY, gtk_widget_hide); systray_main_window_on = 0; } #endif /* HAVE_SYSTRAY */ hide_cover_thumbnail(); gtk_widget_hide(vbox_sep); if (options.playlist_is_embedded) { if (!options.playlist_on) { hide_playlist(); } } #ifdef HAVE_LOOP if (!options.repeat_on) { hide_loop_bar(); } #endif /* HAVE_LOOP */ /* update sliders' tooltips */ if (options.enable_tooltips) { changed_vol(GTK_ADJUSTMENT(adj_vol), NULL); changed_bal(GTK_ADJUSTMENT(adj_bal), NULL); changed_pos(GTK_ADJUSTMENT(adj_pos), NULL); } zero_displays(); if (options.auto_save_playlist) { /* start playback only if no files to be loaded on command line */ int start_playback = (argv[optind] == NULL) && immediate_start; char file[MAXLEN]; snprintf(file, MAXLEN-1, "%s/%s", options.confdir, "playlist.xml"); if (g_file_test(file, G_FILE_TEST_EXISTS) == TRUE) { GSList * list = g_slist_append(NULL, strdup(file)); playlist_load(list, PLAYLIST_LOAD_TAB, NULL, start_playback); } } /* read command line filenames */ { int i; GSList * list = NULL; for (i = optind; argv[i] != NULL; i++) { list = g_slist_append(list, strdup(argv[i])); } if (list != NULL) { process_filenames(list, enqueue, immediate_start, (tab_name != NULL), tab_name); } } /* ensure that at least one playlist has been created */ playlist_ensure_tab_exists(); playlist_set_color(); /* activate jack client and connect ports */ #ifdef HAVE_JACK if (output == JACK_DRIVER) { jack_client_start(); } #endif /* HAVE_JACK */ /* set timeout function */ timeout_tag = aqualung_timeout_add(TIMEOUT_PERIOD, timeout_callback, NULL); if (options.playlist_is_embedded) { gtk_widget_set_sensitive(plist__fileinfo, FALSE); } /* re-apply skin to override possible WM theme */ if (!options.disable_skin_support_settings) { apply_skin(options.skin); } } void adjust_remote_volume(char * str) { char * endptr = NULL; int val = gtk_adjustment_get_value(GTK_ADJUSTMENT(adj_vol)); switch (str[0]) { case 'm': case 'M': val = -41; break; case '=': val = strtol(str + 1, &endptr, 10); if (endptr[0] != '\0') { fprintf(stderr, "Cannot convert to integer value: %s\n", str + 1); return; } break; default: val += strtol(str, &endptr, 10); if (endptr[0] != '\0') { fprintf(stderr, "Cannot convert to integer value: %s\n", str); return; } break; } gtk_adjustment_set_value(GTK_ADJUSTMENT(adj_vol), val); } void process_metablock(metadata_t * meta) { char buf[MAXLEN]; char tmp[MAXLEN]; playlist_t * pl; file_decoder_t * fdec = (file_decoder_t *)meta->fdec; char * artist = NULL; char * album = NULL; char * title = NULL; char * icy_name = NULL; char * icy_descr = NULL; meta_frame_t * frame; frame = metadata_get_frame_by_type(meta, META_FIELD_APIC, NULL); if (frame != NULL) { if (embedded_picture != NULL) { free(embedded_picture); } embedded_picture_size = frame->length; embedded_picture = malloc(embedded_picture_size); if (embedded_picture == NULL) { embedded_picture_size = 0; } else { memcpy(embedded_picture, frame->data, embedded_picture_size); } } else { if (embedded_picture != NULL) { free(embedded_picture); embedded_picture = NULL; } embedded_picture_size = 0; } if ((!httpc_is_url(fdec->filename)) && !options.use_ext_title_format) { return; } buf[0] = '\0'; tmp[0] = '\0'; #ifdef HAVE_LUA // Abuse artist variable if (options.use_ext_title_format && ((artist = application_title_format(fdec)) != NULL)) { strncpy(buf, artist, MAXLEN-1); free(artist); artist = NULL; } #endif /* HAVE_LUA */ if (buf[0] == '\0') { metadata_get_artist(meta, &artist); metadata_get_album(meta, &album); metadata_get_title(meta, &title); metadata_get_icy_name(meta, &icy_name); if ((artist && !is_all_wspace(artist)) || (album && !is_all_wspace(album)) || (title && !is_all_wspace(title))) { make_title_string(tmp, options.title_format, artist, album, title); if (icy_name != NULL) { snprintf(buf, MAXLEN-1, "%s (%s)", tmp, icy_name); } } else if (icy_name != NULL) { strncpy(buf, icy_name, MAXLEN-1); } } if (buf[0] != '\0') { set_title_label(buf); } else { set_title_label(fdec->filename); } if (icy_name == NULL) { return; } buf[0] = '\0'; metadata_get_icy_descr(meta, &icy_descr); if (icy_descr != NULL) { snprintf(buf, MAXLEN-1, "%s (%s)", icy_name, icy_descr); } else { strncpy(buf, icy_name, MAXLEN-1); } /* set playlist_str for playlist entry */ if ((pl = playlist_get_playing()) != NULL) { GtkTreePath * p = playlist_get_playing_path(pl); if (p != NULL) { GtkTreeIter iter; playlist_data_t * data; gtk_tree_model_get_iter(GTK_TREE_MODEL(pl->store), &iter, p); gtk_tree_model_get(GTK_TREE_MODEL(pl->store), &iter, PL_COL_DATA, &data, -1); free_strdup(&data->title, buf); gtk_tree_store_set(pl->store, &iter, PL_COL_NAME, buf, -1); gtk_tree_path_free(p); } } } void flush_rb_disk2gui(void) { char recv_cmd; while (rb_read_space(rb_disk2gui)) { rb_read(rb_disk2gui, &recv_cmd, 1); } } gint timeout_callback(gpointer data) { char cmd; cue_t cue; static double left_gain_shadow; static double right_gain_shadow; char rcmd; static char cmdbuf[MAXLEN]; int rcv_count; static GSList * file_list = NULL; #ifdef HAVE_JACK static int jack_popup_beenthere = 0; #endif /* HAVE_JACK */ metadata_t * meta; while (rb_read_space(rb_disk2gui)) { rb_read(rb_disk2gui, &recv_cmd, 1); switch (recv_cmd) { case CMD_FILEREQ: cmd = CMD_CUE; cue.filename = NULL; cue.voladj = 0.0f; if (!is_file_loaded) break; /* ignore leftover filereq message */ decide_next_track(&cue); if (cue.filename != NULL) { rb_write(rb_gui2disk, &cmd, sizeof(char)); rb_write(rb_gui2disk, (void *)&cue, sizeof(cue_t)); } else { send_cmd = CMD_STOPWOFL; rb_write(rb_gui2disk, &send_cmd, sizeof(char)); } try_waking_disk_thread(); break; case CMD_FILEINFO: while (rb_read_space(rb_disk2gui) < sizeof(fileinfo_t)) ; rb_read(rb_disk2gui, (char *)&fileinfo, sizeof(fileinfo_t)); sample_pos = 0; total_samples = fileinfo.total_samples; status.samples_left = fileinfo.total_samples; status.sample_pos = 0; status.sample_offset = 0; fresh_new_file = fresh_new_file_prev = 0; break; case CMD_STATUS: while (rb_read_space(rb_disk2gui) < sizeof(status_t)) ; rb_read(rb_disk2gui, (char *)&status, sizeof(status_t)); sample_pos = total_samples - status.samples_left; #ifdef HAVE_LOOP if (options.repeat_on && (sample_pos < total_samples * options.loop_range_start || sample_pos > total_samples * options.loop_range_end)) { seek_t seek; send_cmd = CMD_SEEKTO; seek.seek_to_pos = options.loop_range_start * total_samples; rb_write(rb_gui2disk, &send_cmd, 1); rb_write(rb_gui2disk, (char *)&seek, sizeof(seek_t)); try_waking_disk_thread(); refresh_scale_suppress = 2; } #endif /* HAVE_LOOP */ if ((is_file_loaded) && (status.samples_left < 2*status.sample_offset)) { allow_seeks = 0; } else { allow_seeks = 1; } /* treat files with unknown length */ if (total_samples == 0) { allow_seeks = 1; sample_pos = status.sample_pos - status.sample_offset; } if ((!fresh_new_file) && (sample_pos > status.sample_offset)) { fresh_new_file = 1; } if (fresh_new_file && !fresh_new_file_prev) { disp_info = fileinfo; disp_samples = total_samples; if (sample_pos > status.sample_offset) { disp_pos = sample_pos - status.sample_offset; } else { disp_pos = 0; } refresh_displays(); } else { if (sample_pos > status.sample_offset) { disp_pos = sample_pos - status.sample_offset; } else { disp_pos = 0; } if (disp_info.sample_rate != status.sample_rate) { disp_info.sample_rate = status.sample_rate; refresh_displays(); } if (is_file_loaded) { refresh_time_displays(); } } fresh_new_file_prev = fresh_new_file; if (refresh_scale && !refresh_scale_suppress) { if (total_samples == 0) { gtk_adjustment_set_value(GTK_ADJUSTMENT(adj_pos), 0.0f); } else { gtk_adjustment_set_value(GTK_ADJUSTMENT(adj_pos), 100.0 * sample_pos / total_samples); } } if (refresh_scale_suppress > 0) { --refresh_scale_suppress; } show_scale_pos(!total_samples ? FALSE : TRUE); break; case CMD_METABLOCK: while (rb_read_space(rb_disk2gui) < sizeof(metadata_t *)) ; rb_read(rb_disk2gui, (char *)&meta, sizeof(metadata_t *)); process_metablock(meta); break; default: fprintf(stderr, "gui: unexpected command %d recv'd from disk\n", recv_cmd); break; } } /* update volume & balance if necessary */ if ((options.vol != vol_prev) || (options.bal != bal_prev)) { vol_prev = options.vol; vol_lin = (options.vol < -40.5f) ? 0 : db2lin(options.vol); bal_prev = options.bal; if (options.bal >= 0.0f) { left_gain_shadow = vol_lin * db2lin(-0.4f * options.bal); right_gain_shadow = vol_lin; } else { left_gain_shadow = vol_lin; right_gain_shadow = vol_lin * db2lin(0.4f * options.bal); } left_gain = left_gain_shadow; right_gain = right_gain_shadow; } /* receive and execute remote commands, if any */ rcv_count = 0; while (((rcmd = receive_message(aqualung_socket_fd, cmdbuf)) != 0) && (rcv_count < MAX_RCV_COUNT)) { switch (rcmd) { case RCMD_BACK: prev_event(NULL, NULL, NULL); break; case RCMD_PAUSE: if (!options.combine_play_pause) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pause_button), !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(pause_button))); break; } case RCMD_PLAY: gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(play_button), !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(play_button))); break; case RCMD_STOP: stop_event(NULL, NULL, NULL); break; case RCMD_FWD: next_event(NULL, NULL, NULL); break; case RCMD_ADD_FILE: file_list = g_slist_append(file_list, strdup(cmdbuf)); break; case RCMD_ADD_COMMIT: process_filenames(file_list, cmdbuf[0], cmdbuf[1], cmdbuf[2], cmdbuf+3); file_list = NULL; break; case RCMD_VOLADJ: adjust_remote_volume(cmdbuf); break; case RCMD_QUIT: main_window_closing(); break; } ++rcv_count; } /* check for JACK shutdown condition */ #ifdef HAVE_JACK if (output == JACK_DRIVER) { if (jack_is_shutdown) { if (is_file_loaded) { stop_event(NULL, NULL, NULL); } if (!jack_popup_beenthere) { jack_shutdown_window(); if (ports_window) { ports_clicked_close(NULL, NULL); } gtk_widget_set_sensitive(conf__jack, FALSE); jack_popup_beenthere = 1; } } } #endif /* HAVE_JACK */ return TRUE; } void run_gui(void) { gtk_main(); gdk_threads_leave(); return; } void set_buttons_relief(void) { GtkWidget *rbuttons_table[] = { prev_button, stop_button, next_button, play_button, pause_button, repeat_button, repeat_all_button, shuffle_button, playlist_toggle, musicstore_toggle, plugin_toggle }; gint i, n; i = sizeof(rbuttons_table)/sizeof(GtkWidget*); for (n = 0; n < i; n++) { if ((rbuttons_table[n] != pause_button) || !options.combine_play_pause) { gtk_button_set_relief(GTK_BUTTON(rbuttons_table[n]), (options.disable_buttons_relief) ? GTK_RELIEF_NONE : GTK_RELIEF_NORMAL); } } } // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/httpc.h0000644000175000001440000000620510635006520013174 00000000000000/* -*- linux-c -*- Copyright (C) 2007 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: httpc.h 668 2007-06-16 16:16:06Z tszilagyi $ */ #ifndef _HTTPC_H #define _HTTPC_H #define HTTPC_OK 0 #define HTTPC_URL_ERROR -1 #define HTTPC_CONNECTION_ERROR -2 #define HTTPC_HEADER_ERROR -3 #define HTTPC_REDIRECT_ERROR -4 #define HTTPC_SESSION_NORMAL 1 #define HTTPC_SESSION_CHUNKED 2 #define HTTPC_SESSION_STREAM 3 #include "decoder/file_decoder.h" typedef struct { char * status; char * location; int content_length; char * content_type; char * transfer_encoding; int icy_metaint; int icy_br; char * icy_genre; char * icy_name; char * icy_description; } http_header_t; typedef struct { /* original session parameters */ char * URL; int use_proxy; char * proxy; int proxy_port; char * noproxy_domains; int sock; int is_active; http_header_t headers; int type; /* one of HTTPC_SESSION_* */ /* variables for normal download: */ long long byte_pos; /* variables for chunked download: */ char * chunk_buf; int chunk_size; int chunk_pos; int end_of_data; /* variables for stream download: */ int metapos; /* file decoder that uses us - if that is the case */ file_decoder_t * fdec; } http_session_t; int httpc_is_url(const char * str); http_session_t * httpc_new(void); void httpc_del(http_session_t * session); /* Initiate a HTTP/1.1 request. * fdec: associated file_decoder (may be NULL if HTTPC is used * for purposes other than streaming audio data). * URL: string containing location including protocol (http://), * host, port (optional), path. * proxy_URL: may be NULL if none used * proxy_port : integer * start_byte : first byte of content we are interested in, * should be 0L for most cases. * * Return: one of HTTPC_* */ int httpc_init(http_session_t * session, file_decoder_t * fdec, char * URL, int use_proxy, char * proxy, int proxy_port, char * noproxy_domains, long long start_byte); int httpc_read(http_session_t * session, char * buf, int num); int httpc_seek(http_session_t * session, long long offset, int whence); long long httpc_tell(http_session_t * session); void httpc_close(http_session_t * session); int httpc_reconnect(http_session_t * session); void httpc_add_headers_meta(http_session_t * session, metadata_t * meta); #endif /* _HTTPC_H */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/httpc.c0000644000175000001440000006006011243310700013160 00000000000000/* -*- linux-c -*- Copyright (C) 2007 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: httpc.c 1067 2009-07-24 09:35:15Z peterszilagyi $ */ #include #include #include #include #include #include #include #include #include #include #include #include #include "version.h" #include "common.h" #include "options.h" #include "httpc.h" /* Uncomment this to get debug printouts */ /* #define HTTPC_DEBUG */ extern options_t options; int httpc_is_url(const char * str) { if (strlen(str) < 8) return 0; if (str[0] != 'h' && str[0] != 'H') return 0; if (str[1] != 't' && str[1] != 'T') return 0; if (str[2] != 't' && str[2] != 'T') return 0; if (str[3] != 'p' && str[3] != 'P') return 0; if (str[4] != ':') return 0; if (str[5] != '/') return 0; if (str[6] != '/') return 0; return 1; } void free_headers(http_header_t * headers) { if (headers == NULL) return; if (headers->status != NULL) free(headers->status); if (headers->location != NULL) free(headers->location); if (headers->content_type != NULL) free(headers->content_type); if (headers->transfer_encoding != NULL) free(headers->transfer_encoding); if (headers->icy_genre != NULL) free(headers->icy_genre); if (headers->icy_name != NULL) free(headers->icy_name); if (headers->icy_description != NULL) free(headers->icy_description); } /* Checks whether bytes can be read/written from/to the socket within * the specified time out period. Adapted from libcddb source code. * * sock The socket to read from. * timeout Number of seconds after which to time out. * to_write nonzero if checking for writing, zero for reading. * * return nonzero if reading/writing is possible, zero otherwise. */ int sock_ready(int sock, int timeout, int to_write) { fd_set fds; struct timeval tv; int ret; tv.tv_sec = timeout; tv.tv_usec = 0; FD_ZERO(&fds); FD_SET(sock, &fds); if (to_write) { ret = select(sock + 1, NULL, &fds, NULL, &tv) ; } else { ret = select(sock + 1, &fds, NULL, NULL, &tv) ; } if (ret <= 0) { if (ret == 0) { errno = ETIMEDOUT; fprintf(stderr, "httpc: socket I/O timed out\n"); } return 0; } return 1; } #define sock_can_read(s,t) sock_ready(s, t, 0) #define sock_can_write(s,t) sock_ready(s, t, 1) /* Timeout-supporting version of connect(). Adapted from libcddb source. */ int timeout_connect(int sockfd, const struct sockaddr *addr, size_t len, int timeout) { int got_error = 0; int flags; flags = fcntl(sockfd, F_GETFL, 0); flags |= O_NONBLOCK; if (fcntl(sockfd, F_SETFL, flags) == -1) { return -1; } if (connect(sockfd, addr, len) < 0) { if (errno == EINPROGRESS) { int ret; fd_set wfds; struct timeval tv; socklen_t l; tv.tv_sec = timeout; tv.tv_usec = 0; FD_ZERO(&wfds); FD_SET(sockfd, &wfds); ret = select(sockfd + 1, NULL, &wfds, NULL, &tv); switch (ret) { case 0: fprintf(stderr, "httpc: connect() timed out\n"); errno = ETIMEDOUT; case -1: got_error = -1; default: l = sizeof(ret); getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &ret, &l); if (ret) { errno = ret; got_error = -1; } } } else { got_error = -1; } } return got_error; } int open_socket(char * hostname, unsigned short portnum) { struct sockaddr_in sa; struct hostent * hp; int s; if ((hp = gethostbyname(hostname)) == NULL) { fprintf(stderr, "open_socket: gethostbyname() failed on %s\n", hostname); return -1; } memset(&sa, 0, sizeof(sa)); memcpy((char *)&sa.sin_addr, hp->h_addr, hp->h_length); sa.sin_family = hp->h_addrtype; sa.sin_port = htons((u_short)portnum); if ((s = socket(hp->h_addrtype, SOCK_STREAM, 0)) < 0) { fprintf(stderr, "open_socket: socket(): %s\n", strerror(errno)); return -1; } if (timeout_connect(s, (struct sockaddr *)&sa, sizeof (sa), options.inet_timeout) < 0) { fprintf(stderr, "open_socket: connect(): %s\n", strerror(errno)); close(s); return -1; } #ifdef HTTPC_DEBUG printf("socket successfully opened to %s:%d\n", hostname, portnum); #endif /* HTTPC_DEBUG */ return s; } int read_socket(int s, char * buf, int n) { int bcount; int br; bcount = 0; br = 0; while (bcount < n) { if (!sock_can_read(s, options.inet_timeout)) { return -1; } if ((br = recv(s, buf, n-bcount, 0)) > 0) { bcount += br; buf += br; } else if (br < 0) { return -1; } else { break; } } return bcount; } int read_sock_line(int s, char * buf, int n) { int k; int ret; for (k = 0; k < n; k++) { if (!sock_can_read(s, options.inet_timeout)) { return -1; } if ((ret = recv(s, buf+k, 1, 0)) < 0) { return -1; } if (ret == 0) { buf[k] = '\0'; break; } if (buf[k] == '\n') { if (k > 0 && buf[k-1] == '\r') { buf[k-1] = '\0'; } else { buf[k] = '\0'; } break; } if (buf[k] == '\0') { break; } } return strlen(buf); } int write_socket(int s, char * buf, int n) { int bcount; int bw; bcount = 0; bw = 0; while (bcount < n) { if (!sock_can_write(s, options.inet_timeout)) { return -1; } if ((bw = send(s, buf, n-bcount, 0)) > 0) { bcount += bw; buf += bw; } else if (bw < 0) { return -1; } } return bcount; } char * strip_whitespace(char * str) { int i, j; for (i = 0; str[i] != '\0' && (str[i] == ' ' || str[i] == '\t'); i++); if (str[i] == '\0') { str[0] = '\0'; return str; } for (j = strlen(str)-1; str[j] == ' ' || str[j] == '\t'; j--); memmove(str, str+i, j-i+1); str[j-i+1] = '\0'; return str; } int parse_field(char * line, char * name, char * value) { if (line[0] == ' ' || line[0] == '\t') { name[0] = '\0'; strcpy(value, strip_whitespace(line)); } else { char * c = strstr(line, ":"); if (c == NULL) return -1; strncpy(name, line, c-line); name[c-line] = '\0'; strncpy(value, c+1, strlen(c)-1); value[strlen(c)-1] = '\0'; strip_whitespace(name); strip_whitespace(value); } return 0; } int check_http_response(char * line, char * resp) { char http10[16]; char http11[16]; snprintf(http10, 15, "HTTP/1.0 %s", resp); snprintf(http11, 15, "HTTP/1.1 %s", resp); return (strstr(line, http10) != NULL) || (strstr(line, http11) != NULL); } int parse_http_headers(http_session_t * session) { char line[1024]; char name[1024]; char value[1024]; int s = session->sock; http_header_t * header = &session->headers; read_sock_line(s, line, sizeof(line)); #ifdef HTTPC_DEBUG printf("line = '%s'\n", line); #endif /* HTTPC_DEBUG */ if (check_http_response(line, "4")) { header->status = strdup(line); return -1; } if (check_http_response(line, "5")) { header->status = strdup(line); return -2; } header->status = strdup(line); while (1) { char new_name[1024]; char new_value[1024]; read_sock_line(s, line, sizeof(line)); if (line[0] == '\0') break; if (parse_field(line, new_name, new_value) == -1) return -3; if (new_name[0] == '\0') { snprintf(value, sizeof(value), "%s %s", value, new_value); } else { strcpy(name, new_name); strcpy(value, new_value); } if (strcasecmp(name, "location") == 0) { header->location = strdup(value); } else if (strcasecmp(name, "content-length") == 0) { int l; if (sscanf(value, "%d", &l) != 1) { #ifdef HTTPC_DEBUG printf("sscanf error (content-length)\n"); #endif /* HTTPC_DEBUG */ return -3; } else { header->content_length = l; } } else if (strcasecmp(name, "content-type") == 0) { header->content_type = strdup(value); } else if (strcasecmp(name, "transfer-encoding") == 0) { header->transfer_encoding = strdup(value); } else if (strcasecmp(name, "icy-metaint") == 0) { int l; if (sscanf(value, "%d", &l) != 1) { #ifdef HTTPC_DEBUG printf("sscanf error (icy-metaint)\n"); #endif /* HTTPC_DEBUG */ return -3; } else { header->icy_metaint = l; } } else if (strcasecmp(name, "icy-br") == 0) { int l; if (sscanf(value, "%d", &l) != 1) { if (sscanf(value, "Quality %d", &l) != 1) { #ifdef HTTPC_DEBUG printf("sscanf error (icy-br)\n"); #endif /* HTTPC_DEBUG */ return -3; } else { header->icy_br = l; } } else { header->icy_br = l; } } else if (strcasecmp(name, "icy-genre") == 0) { header->icy_genre = strdup(value); } else if (strcasecmp(name, "icy-name") == 0) { header->icy_name = strdup(value); } else if (strcasecmp(name, "icy-description") == 0) { header->icy_description = strdup(value); } #ifdef HTTPC_DEBUG printf("name = '%s' value = '%s'\n", name, value); #endif /* HTTPC_DEBUG */ } return 0; } int parse_chunk_size(char * line) { int ret; char * p; if ((p = strstr(line, ";")) != NULL) { *p = '\0'; } if (sscanf(line, "%x", &ret) != 1) { return -1; } return ret; } void make_http_request_text(char * host, int port, char * path, int use_proxy, char * proxy, long long start_byte, char * msg, int msg_len) { char extra_header[1024]; if (start_byte != 0) { snprintf(extra_header, sizeof(extra_header), "Range: bytes=%lld-\r\n", start_byte); } else { extra_header[0] = '\0'; } if (!use_proxy) { if (port == 80) { snprintf(msg, msg_len, "GET %s HTTP/1.1\r\n" "Host: %s\r\n" "User-Agent: Aqualung/%s\r\n" "icy-metadata: 1\r\n" "%s" "Connection: close\r\n\r\n", path, host, AQUALUNG_VERSION, extra_header); } else { snprintf(msg, msg_len, "GET %s HTTP/1.1\r\n" "Host: %s:%d\r\n" "User-Agent: Aqualung/%s\r\n" "icy-metadata: 1\r\n" "%s" "Connection: close\r\n\r\n", path, host, port, AQUALUNG_VERSION, extra_header); } } else { if (port == 80) { snprintf(msg, msg_len, "GET http://%s%s HTTP/1.1\r\n" "Host: %s\r\n" "User-Agent: Aqualung/%s\r\n" "icy-metadata: 1\r\n" "%s" "Connection: close\r\n\r\n", host, path, host, AQUALUNG_VERSION, extra_header); } else { snprintf(msg, msg_len, "GET http://%s:%d%s HTTP/1.1\r\n" "Host: %s:%d\r\n" "User-Agent: Aqualung/%s\r\n" "icy-metadata: 1\r\n" "%s" "Connection: close\r\n\r\n", host, port, path, host, port, AQUALUNG_VERSION, extra_header); } } } http_session_t * httpc_new(void) { http_session_t * session = (http_session_t *)malloc(sizeof(http_session_t)); if (session == NULL) return NULL; memset(session, 0, sizeof(http_session_t)); return session; } void httpc_del(http_session_t * session) { if (session == NULL) { return; } free(session->URL); if (session->proxy != NULL) free(session->proxy); if (session->noproxy_domains != NULL) free(session->noproxy_domains); free_headers(&session->headers); free(session); } void httpc_close(http_session_t * session) { if (session->is_active) { #ifdef HTTPC_DEBUG printf("closing HTTP connection\n"); #endif /* HTTPC_DEBUG */ close(session->sock); session->is_active = 0; } } /* return 1 if host has to be accessed without the proxy */ int noproxy_for_host(const char * noproxy_domains, const char * host) { char * s; char * nd; if (noproxy_domains == NULL) return 0; nd = strdup(noproxy_domains); s = strtok(nd, ","); while (s != NULL) { char * str = strip_whitespace(s); if (strstr(host, str) != NULL) { #ifdef HTTPC_DEBUG printf("%s matches %s, no proxy.\n", str, host); #endif /* HTTPC_DEBUG */ free(nd); return 1; } s = strtok(NULL, ","); } free(nd); return 0; } int httpc_init(http_session_t * session, file_decoder_t * fdec, char * URL, int use_proxy, char * proxy, int proxy_port, char * noproxy_domains, long long start_byte) { char * p; char host[1024]; char port_str[8]; int port; char msg_buf[1024]; memset(session, 0, sizeof(http_session_t)); if (!httpc_is_url(URL)) return HTTPC_URL_ERROR; session->URL = strdup(URL); if (use_proxy) { session->use_proxy = use_proxy; session->proxy = strdup(proxy); session->proxy_port = proxy_port; session->noproxy_domains = strdup(noproxy_domains); } URL += strlen("http://"); if ((p = strstr(URL, ":")) != NULL) { unsigned int l = p - URL; if (l > sizeof(host)) { return HTTPC_URL_ERROR; } strncpy(host, URL, l); host[l] = '\0'; URL += l+1; if ((p = strstr(URL, "/")) != NULL) { unsigned int m = p - URL; if (m > sizeof(port_str)) { return HTTPC_URL_ERROR; } strncpy(port_str, URL, m); port_str[m] = '\0'; URL += m; } else { strncpy(port_str, URL, sizeof(port_str)); URL = "/"; } if (sscanf(port_str, "%d", &port) != 1) { return HTTPC_URL_ERROR; } } else { if ((p = strstr(URL, "/")) != NULL) { unsigned int l = p - URL; if (l > sizeof(host)) { return HTTPC_URL_ERROR; } strncpy(host, URL, l); host[l] = '\0'; URL += l; port = 80; } else { strncpy(host, URL, sizeof(host)); port = 80; URL = "/"; } } make_http_request_text(host, port, URL, use_proxy, proxy, start_byte, msg_buf, sizeof(msg_buf)); #ifdef HTTPC_DEBUG printf("%s\n", msg_buf); #endif /* HTTPC_DEBUG */ if (!use_proxy || noproxy_for_host(noproxy_domains, host)) { session->sock = open_socket(host, port); } else { session->sock = open_socket(proxy, proxy_port); } if (session->sock < 0) { return HTTPC_CONNECTION_ERROR; } write_socket(session->sock, msg_buf, strlen(msg_buf)); if (parse_http_headers(session) != 0) { close(session->sock); #ifdef HTTPC_DEBUG printf("http header error, server error or resource not found\n"); #endif /* HTTPC_DEBUG */ return HTTPC_HEADER_ERROR; } if (check_http_response(session->headers.status, "30")) { /* redirect */ if (session->headers.location != NULL) { char * location = strdup(session->headers.location); int ret; #ifdef HTTPC_DEBUG printf("redirecting to %s\n", session->headers.location); #endif /* HTTPC_DEBUG */ close(session->sock); free(session->URL); free_headers(&session->headers); ret = httpc_init(session, fdec, location, use_proxy, proxy, proxy_port, noproxy_domains, 0L); free(location); return ret; } else { close(session->sock); #ifdef HTTPC_DEBUG printf("redirect error\n"); #endif /* HTTPC_DEBUG */ return HTTPC_REDIRECT_ERROR; } } else if ((session->headers.content_type != NULL) && (strcasecmp(session->headers.content_type, "audio/x-mpegurl") == 0)) { char buf[1024]; int ret; read_sock_line(session->sock, buf, sizeof(buf)); #ifdef HTTPC_DEBUG printf("following x-mpegurl to %s\n", buf); #endif /* HTTPC_DEBUG */ close(session->sock); free(session->URL); free_headers(&session->headers); ret = httpc_init(session, fdec, buf, use_proxy, proxy, proxy_port, noproxy_domains, 0L); return ret; } if (session->headers.content_length != 0) { session->type = HTTPC_SESSION_NORMAL; } else if ((session->headers.transfer_encoding != NULL) && (strcasecmp(session->headers.transfer_encoding, "chunked") == 0)) { session->type = HTTPC_SESSION_CHUNKED; } else { session->type = HTTPC_SESSION_STREAM; } session->is_active = 1; session->byte_pos = start_byte; session->fdec = fdec; if (fdec != NULL && fdec->meta_cb != NULL) { fdec->meta = metadata_new(); fdec->meta->fdec = fdec; httpc_add_headers_meta(session, fdec->meta); fdec->meta_cb(fdec->meta, fdec->meta_cbdata); } #ifdef HTTPC_DEBUG printf("HTTP connection successfully opened, type = %d\n", session->type); #endif /* HTTPC_DEBUG */ return 0; } int httpc_read_normal(http_session_t * session, char * buf, int num) { int sock = session->sock; int tr = session->headers.content_length - session->byte_pos; int n_read; if (!session->is_active) { #ifdef HTTPC_DEBUG printf("[HTTPC] Reopening stream\n"); #endif /* HTTPC_DEBUG */ httpc_reconnect(session); } #ifdef HTTPC_DEBUG printf("httpc_read_normal num = %d, pos = %lld, ", num, session->byte_pos); #endif /* HTTPC_DEBUG */ if (tr > num) { tr = num; } n_read = read_socket(sock, buf, tr); if (n_read < 0) { return -1; } session->byte_pos += n_read; return n_read; } int httpc_read_chunked(http_session_t * session, char * buf, int num) { int sock = session->sock; int chunk_size = session->chunk_size; int chunk_pos = session->chunk_pos; int buf_pos = 0; char line[1024]; #ifdef HTTPC_DEBUG printf("httpc_read_chunked\n"); #endif /* HTTPC_DEBUG */ while (buf_pos < num && !session->end_of_data) { if (chunk_size - chunk_pos > 0) { int tw = chunk_size - chunk_pos; if (tw > num - buf_pos) tw = num - buf_pos; #ifdef HTTPC_DEBUG printf("buf_pos = %d chunk_size = %d chunk_pos = %d tw = %d\n", buf_pos, chunk_size, chunk_pos, tw); #endif /* HTTPC_DEBUG */ memcpy(buf + buf_pos, session->chunk_buf + chunk_pos, tw); chunk_pos += tw; buf_pos += tw; } if (chunk_pos == chunk_size) { /* read next chunk */ chunk_pos = 0; if (chunk_size > 0) free(session->chunk_buf); read_sock_line(sock, line, sizeof(line)); chunk_size = parse_chunk_size(line); if (chunk_size > 0) { int n_read; #ifdef HTTPC_DEBUG printf("chunk size = %d\n", chunk_size); #endif /* HTTPC_DEBUG */ session->chunk_buf = malloc(chunk_size); n_read = read_socket(sock, session->chunk_buf, chunk_size); if (n_read != chunk_size) { #ifdef HTTPC_DEBUG printf("httpc_read_chunked: premature end of chunk!\n"); #endif /* HTTPC_DEBUG */ } read_sock_line(sock, line, sizeof(line)); } else { #ifdef HTTPC_DEBUG printf("end of data\n"); #endif /* HTTPC_DEBUG */ session->end_of_data = 1; } } } session->chunk_size = chunk_size; session->chunk_pos = chunk_pos; return buf_pos; } void httpc_add_headers_meta(http_session_t * session, metadata_t * meta) { if (session->headers.icy_name != NULL) { metadata_add_frame_from_keyval(meta, META_TAG_GEN_STREAM, "Icy-Name", session->headers.icy_name); } if (session->headers.icy_genre != NULL) { metadata_add_frame_from_keyval(meta, META_TAG_GEN_STREAM, "Icy-Genre", session->headers.icy_genre); } if (session->headers.icy_description != NULL) { metadata_add_frame_from_keyval(meta, META_TAG_GEN_STREAM, "Icy-Description", session->headers.icy_description); } } int httpc_demux(http_session_t * session) { int meta_len; char meta_len_buf; char * meta_buf; if (read_socket(session->sock, &meta_len_buf, 1) != 1) return -1; meta_len = 16 * meta_len_buf; meta_buf = calloc(meta_len+1, 1); if (read_socket(session->sock, meta_buf, meta_len) != meta_len) return -1; meta_buf[meta_len] = '\0'; if (meta_len > 0 && session->fdec != NULL && session->fdec->meta_cb != NULL) { metadata_t * meta = metadata_from_mpeg_stream_data(meta_buf); meta->fdec = session->fdec; session->fdec->meta = meta; httpc_add_headers_meta(session, meta); session->fdec->meta_cb(meta, session->fdec->meta_cbdata); } free(meta_buf); return 0; } int httpc_read_stream_simple(http_session_t * session, char * buf, int num) { int n_read = read_socket(session->sock, buf, num); if (n_read < 0) { return 0; } return n_read; } int httpc_read_stream(http_session_t * session, char * buf, int num) { int metaint = session->headers.icy_metaint; int n_read, n_read2; if (metaint == 0) { return httpc_read_stream_simple(session, buf, num); } if (metaint - session->metapos >= num) { n_read = read_socket(session->sock, buf, num); if (n_read < 0) return 0; session->metapos += n_read; return n_read; } else { n_read = metaint - session->metapos; n_read2 = num - n_read; n_read = read_socket(session->sock, buf, n_read); if (n_read < 0) return 0; httpc_demux(session); while (n_read2 > metaint) { int n = read_socket(session->sock, buf + n_read, metaint); if (n < 0) return 0; httpc_demux(session); n_read2 -= n; n_read += n; } if (n_read2 > 0) { n_read2 = read_socket(session->sock, buf + n_read, n_read2); if (n_read2 < 0) return 0; session->metapos = n_read2; } else { session->metapos = 0; } return n_read + n_read2; } } int httpc_read(http_session_t * session, char * buf, int num) { switch (session->type) { case HTTPC_SESSION_NORMAL: return httpc_read_normal(session, buf, num); case HTTPC_SESSION_CHUNKED: return httpc_read_chunked(session, buf, num); case HTTPC_SESSION_STREAM: return httpc_read_stream(session, buf, num); default: fprintf(stderr, "httpc_read: unknown session type = %d\n", session->type); return 0; } } int httpc_reconnect(http_session_t * session) { char * URL; int use_proxy = 0; char * proxy = NULL; int proxy_port = 0; char * noproxy_domains = NULL; long long start_byte = 0L; int content_length = 0; int ret; URL = strdup(session->URL); if (session->use_proxy) { use_proxy = session->use_proxy; proxy = strdup(session->proxy); proxy_port = session->proxy_port; noproxy_domains = strdup(session->noproxy_domains); } if (session->type == HTTPC_SESSION_NORMAL) { start_byte = session->byte_pos; content_length = session->headers.content_length; } else { start_byte = 0; } ret = httpc_init(session, session->fdec, URL, use_proxy, proxy, proxy_port, noproxy_domains, start_byte); if (ret != HTTPC_OK) { fprintf(stderr, "http_reconnect: HTTP session reopen failed, ret = %d\n", ret); } if (session->type == HTTPC_SESSION_NORMAL) { session->headers.content_length = content_length; } free(URL); if (proxy != NULL) free(proxy); if (noproxy_domains != NULL) free(noproxy_domains); return ret; } int httpc_seek(http_session_t * session, long long offset, int whence) { if (session->type != HTTPC_SESSION_NORMAL) return -1; #ifdef HTTPC_DEBUG printf("[HTTPC_SEEK] offset = %lld whence = %d byte_pos = %lld\n", offset, whence, session->byte_pos); #endif /* HTTPC_DEBUG */ switch (whence) { case SEEK_SET: if (offset == session->byte_pos) { #ifdef HTTPC_DEBUG printf("noop SEEK_SET\n"); #endif /* HTTPC_DEBUG */ return session->byte_pos; } break; case SEEK_CUR: if (offset == 0) { #ifdef HTTPC_DEBUG printf("noop SEEK_CUR\n"); #endif /* HTTPC_DEBUG */ return session->byte_pos; } break; case SEEK_END: if (session->headers.content_length - offset == session->byte_pos) { #ifdef HTTPC_DEBUG printf("noop SEEK_END\n"); #endif /* HTTPC_DEBUG */ return session->byte_pos; } break; } if (session->is_active) { #ifdef HTTPC_DEBUG printf("[HTTPC] Closing stream\n"); #endif /* HTTPC_DEBUG */ httpc_close(session); } switch (whence) { case SEEK_SET: #ifdef HTTPC_DEBUG printf("[HTTPC] SEEK_SET offset = %lld\n", offset); #endif /* HTTPC_DEBUG */ if (offset > session->headers.content_length) { offset = session->headers.content_length; } session->byte_pos = offset; break; case SEEK_CUR: #ifdef HTTPC_DEBUG printf("[HTTPC] SEEK_CUR offset = %lld\n", offset); #endif /* HTTPC_DEBUG */ if (offset + session->byte_pos > session->headers.content_length) { session->byte_pos = session->headers.content_length; } else { session->byte_pos += offset; } break; case SEEK_END: #ifdef HTTPC_DEBUG printf("[HTTPC] SEEK_END offset = %lld\n", offset); #endif /* HTTPC_DEBUG */ if (offset > session->headers.content_length - session->byte_pos) { session->byte_pos = 0L; } else { session->byte_pos = session->headers.content_length - offset; } break; } return session->byte_pos; } long long httpc_tell(http_session_t * session) { if (session->type != HTTPC_SESSION_NORMAL) return -1; #ifdef HTTPC_DEBUG printf("[HTTPC] TELL = %lld\n", session->byte_pos); #endif /* HTTPC_DEBUG */ return session->byte_pos; } // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/i18n.h0000644000175000001440000000027210612341733012632 00000000000000#ifndef _I18N_H #define _I18N_H #include #include #define _(Text) gettext(Text) #define N_(Text) gettext_noop(Text) #define X_(Text) Text #endif /* _I18N_H */ aqualung-0.9beta11/src/ifp_device.h0000644000175000001440000000242710657140026014155 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi (C) 2006 Tomasz Maka This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: ifp_device.h 758 2007-08-10 16:23:29Z pasp $ */ #ifndef _IFP_DEVICE_H #define _IFP_DEVICE_H #define PARENTDIR ("..") #define DIRID ("

    ") enum { COLUMN_NAME = 0, COLUMN_TYPE_SIZE }; enum { TYPE_NONE = 0, TYPE_DIR, TYPE_FILE }; enum { UPLOAD_MODE = 0, DOWNLOAD_MODE }; void aifp_transfer_files(gint mode); #endif /* _IFP_DEVICE_H */ // vim: shiftwidth=8:tabstop=8:softtabstop=8: aqualung-0.9beta11/src/ifp_device.c0000644000175000001440000014300411324131225014136 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi (C) 2006 Tomasz Maka This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: ifp_device.c 1099 2010-01-12 19:32:47Z pasp $ */ #include #ifdef HAVE_IFP #include #include #include #include #include #include #include #include #include #include #include #include "common.h" #include "utils_gui.h" #include "i18n.h" #include "options.h" #include "gui_main.h" #include "ifp_device.h" #include "playlist.h" #include "decoder/file_decoder.h" extern options_t options; extern GtkWidget * playlist_window; extern GtkWidget * main_window; extern GtkTooltips * aqualung_tooltips; void aifp_close_device(void); gint aifp_directory_listing(gchar *name); void aifp_check_size(void); void aifp_update_info(void); struct usb_device *dev = NULL; usb_dev_handle *dh; struct ifp_device ifpdev; gchar remote_path[MAXLEN], remote_item[MAXLEN]; gchar dest_dir[MAXLEN], dest_file[MAXLEN]; guint songs_size, number_of_songs; gint battery_status, capacity, freespace, abort_pressed; gint valid_files, transfer_active, remote_type; gint transfer_mode; GtkWidget * aifp_window = NULL; GtkWidget * upload_download_button; GtkWidget * abort_button; GtkWidget * close_button; GtkWidget * mkdir_button; GtkWidget * rndir_button; GtkWidget * rmdir_button; GtkWidget * local_path_entry; GtkWidget * local_path_browse_button; GtkWidget * aifp_close_when_ready_check; GtkWidget * label_songs; GtkWidget * label_songs_size; GtkWidget * label_model; GtkWidget * progressbar_battery; GtkWidget * progressbar_freespace; GtkWidget * progressbar_cf; GtkWidget * progressbar_op; GtkWidget * aifp_file_entry; GtkWidget * list; GtkListStore * list_store = NULL; GtkWidget *mkdir_dialog; GtkWidget *rename_dialog; /* list of accepted file extensions */ char * valid_extensions_ifp[] = { "mp3", "ogg", "wma", "asf", NULL }; int aifp_window_close(GtkWidget * widget, gpointer * data) { aifp_close_device(); gtk_window_get_size(GTK_WINDOW(aifp_window), &options.ifpmanager_size_x, &options.ifpmanager_size_y); gtk_widget_destroy(aifp_window); aifp_window = NULL; return 0; } void abort_transfer_cb (GtkButton *button, gpointer user_data) { abort_pressed = 1; } static int update_progress (void *context, struct ifp_transfer_status *status) { gchar temp[MAXLEN]; gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progressbar_cf), (float)status->file_bytes/status->file_total); sprintf(temp, _("%.1f MB / %.1f MB"), (float)status->file_bytes/(1024*1024), (float)status->file_total/(1024*1024)); gtk_progress_bar_set_text (GTK_PROGRESS_BAR (progressbar_cf), temp); if (abort_pressed) { return 1; } else { return 0; } } int upload_songs_cb_foreach(playlist_t * pl, GtkTreeIter * iter, void * data) { int * n = (int *)data; char * file; char temp[MAXLEN]; playlist_data_t * pldata; if (abort_pressed) { return 0; } gtk_tree_model_get(GTK_TREE_MODEL(pl->store), iter, PL_COL_DATA, &pldata, -1); if (!g_file_test(pldata->file, G_FILE_TEST_EXISTS)) { return 0; } file = g_path_get_basename(pldata->file); strncpy(dest_file, remote_path, MAXLEN-1); if (strlen(remote_path) != 1) { strncat(dest_file, "\\", MAXLEN-1); } strncat(dest_file, file, MAXLEN-1); gtk_entry_set_text(GTK_ENTRY(aifp_file_entry), file); gtk_editable_set_position(GTK_EDITABLE(aifp_file_entry), -1); gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progressbar_op), (float)(*n + 1) / number_of_songs); sprintf(temp, _("%d / %d files"), *n + 1, number_of_songs); gtk_progress_bar_set_text(GTK_PROGRESS_BAR (progressbar_op), temp); ifp_upload_file(&ifpdev, pldata->file, dest_file, update_progress, NULL); aifp_update_info(); g_free(file); (*n)++; return 0; } gboolean download_songs_cb_foreach (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data) { gchar *file; gchar temp[MAXLEN]; int * n = (int *)data; if (abort_pressed) { return 0; } gtk_tree_model_get (model, iter, COLUMN_NAME, &file, -1); if (strncmp(file, PARENTDIR, 2)) { strncpy(remote_item, remote_path, MAXLEN-1); if (strlen(remote_path) != 1) { strncat(remote_item, "\\", MAXLEN-1); } strncat(remote_item, file, MAXLEN-1); strncpy(dest_file, dest_dir, MAXLEN-1); strncat(dest_file, "/", MAXLEN-1); strncat(dest_file, file, MAXLEN-1); gtk_entry_set_text(GTK_ENTRY(aifp_file_entry), file); gtk_editable_set_position(GTK_EDITABLE(aifp_file_entry), -1); gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progressbar_op), (float)(*n + 1) / number_of_songs); if (ifp_is_file (&ifpdev, remote_item) == TRUE) { sprintf(temp, _("%d / %d files"), *n + 1, number_of_songs); gtk_progress_bar_set_text(GTK_PROGRESS_BAR (progressbar_op), temp); ifp_download_file (&ifpdev, remote_item, dest_file, update_progress, NULL); } else { sprintf(temp, _("%d / %d directories"), *n + 1, number_of_songs); gtk_progress_bar_set_text(GTK_PROGRESS_BAR (progressbar_op), temp); ifp_download_dir (&ifpdev, remote_item, dest_file, update_progress, NULL); } aifp_update_info(); g_free(file); (*n)++; } return TRUE; } void upload_download_songs_cb(GtkButton * button, gpointer user_data) { int n = 0; playlist_t * pl = playlist_get_current(); if (transfer_mode == UPLOAD_MODE && pl == NULL) { return; } if (transfer_mode == DOWNLOAD_MODE) { if (access(dest_dir, W_OK) == -1) { message_dialog(_("Error"), aifp_window, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, NULL, _("Cannot write to selected directory. Please select another directory.")); return; } } transfer_active = 1; gtk_widget_set_sensitive(abort_button, TRUE); gtk_widget_set_sensitive(upload_download_button, FALSE); gtk_widget_set_sensitive(close_button, FALSE); if (transfer_mode == UPLOAD_MODE) { gtk_widget_set_sensitive(mkdir_button, FALSE); } else { gtk_widget_set_sensitive(local_path_browse_button, FALSE); } gtk_widget_set_sensitive(list, FALSE); gtk_widget_set_sensitive(rndir_button, FALSE); gtk_widget_set_sensitive(rmdir_button, FALSE); if (transfer_mode == UPLOAD_MODE) { playlist_foreach_selected(pl, (void *)upload_songs_cb_foreach, &n); } else { GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(list)); gtk_tree_selection_selected_foreach(selection, (GtkTreeSelectionForeachFunc)download_songs_cb_foreach, &n); } gtk_widget_set_sensitive(abort_button, FALSE); gtk_widget_set_sensitive(close_button, TRUE); gtk_widget_set_sensitive(list, TRUE); if (!abort_pressed) { gtk_widget_set_sensitive(upload_download_button, FALSE); gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progressbar_op), _("Done")); gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progressbar_cf), _("Done")); } else { gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progressbar_op), _("Aborted...")); gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progressbar_op), 0.0); gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progressbar_cf), _("Aborted...")); gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progressbar_cf), 0.0); gtk_widget_set_sensitive(upload_download_button, TRUE); } aifp_update_info(); gtk_widget_set_sensitive(abort_button, FALSE); gtk_widget_set_sensitive(upload_download_button, TRUE); gtk_widget_set_sensitive(close_button, TRUE); if (transfer_mode == UPLOAD_MODE) { gtk_widget_set_sensitive(mkdir_button, TRUE); } else { gtk_widget_set_sensitive(local_path_browse_button, TRUE); } gtk_widget_set_sensitive(list, TRUE); gtk_widget_set_sensitive(rndir_button, TRUE); gtk_widget_set_sensitive(rmdir_button, TRUE); gtk_widget_grab_focus(list); gtk_entry_set_text(GTK_ENTRY(aifp_file_entry), _("None")); aifp_directory_listing(NULL); aifp_update_info(); if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(aifp_close_when_ready_check)) && !abort_pressed) { aifp_window_close(NULL, NULL); } abort_pressed = 0; transfer_active = 0; } int mkdir_key_press (GtkWidget *widget, GdkEventKey *event, gpointer data) { if (event->keyval == GDK_Return) { gtk_dialog_response(GTK_DIALOG (mkdir_dialog), GTK_RESPONSE_OK); } return FALSE; } void aifp_create_directory_cb (GtkButton *button, gpointer user_data) { GtkWidget *name_entry; gint response; gchar temp[MAXLEN]; mkdir_dialog = gtk_message_dialog_new (GTK_WINDOW(aifp_window), GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL, GTK_MESSAGE_INFO, GTK_BUTTONS_OK_CANCEL, _("Please enter directory name.")); gtk_window_set_title(GTK_WINDOW(mkdir_dialog), _("Create directory")); name_entry = gtk_entry_new(); g_signal_connect (G_OBJECT(name_entry), "key_press_event", G_CALLBACK(mkdir_key_press), NULL); gtk_entry_set_max_length(GTK_ENTRY(name_entry), 64); gtk_widget_set_size_request(GTK_WIDGET(name_entry), 300, -1); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(mkdir_dialog)->vbox), name_entry, FALSE, FALSE, 6); gtk_widget_show_all (mkdir_dialog); response = aqualung_dialog_run(GTK_DIALOG(mkdir_dialog)); if (response == GTK_RESPONSE_OK) { strncpy(temp, remote_path, MAXLEN-1); if (strlen(remote_path) != 1) { strncat(temp, "\\", MAXLEN-1); } strncat(temp, gtk_entry_get_text(GTK_ENTRY(name_entry)), MAXLEN-1); if (strlen(temp)) { ifp_mkdir(&ifpdev, temp); aifp_directory_listing(temp); aifp_update_info(); } } gtk_widget_destroy(mkdir_dialog); } gint rename_key_press (GtkWidget *widget, GdkEventKey *event, gpointer data) { if (event->keyval == GDK_Return) { gtk_dialog_response(GTK_DIALOG (rename_dialog), GTK_RESPONSE_OK); } return FALSE; } void aifp_rename_item_cb (GtkButton *button, gpointer user_data) { GtkWidget *name_entry; gchar temp[MAXLEN]; gint response; const gchar * text; if (strncmp(remote_item, PARENTDIR, 2)) { rename_dialog = gtk_message_dialog_new (GTK_WINDOW(aifp_window), GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL, GTK_MESSAGE_INFO, GTK_BUTTONS_OK_CANCEL, _("Please enter a new name.")); gtk_window_set_title(GTK_WINDOW(rename_dialog), _("Rename")); name_entry = gtk_entry_new(); g_signal_connect (G_OBJECT(name_entry), "key_press_event", G_CALLBACK(rename_key_press), NULL); gtk_entry_set_max_length(GTK_ENTRY(name_entry), 64); gtk_widget_set_size_request(GTK_WIDGET(name_entry), 300, -1); gtk_entry_set_text(GTK_ENTRY(name_entry), remote_item); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(rename_dialog)->vbox), name_entry, FALSE, FALSE, 6); gtk_widget_show_all (rename_dialog); response = aqualung_dialog_run(GTK_DIALOG(rename_dialog)); if (response == GTK_RESPONSE_OK) { text = gtk_entry_get_text(GTK_ENTRY(name_entry)); strncpy(temp, remote_path, MAXLEN-1); if (strlen(remote_path) != 1) { strncat(temp, "\\", MAXLEN-1); } strncat(temp, text, MAXLEN-1); if (strlen(text)) { strncpy(dest_file, remote_path, MAXLEN-1); if (strlen(remote_path) != 1) { strncat(dest_file, "\\", MAXLEN-1); } strncat(dest_file, remote_item, MAXLEN-1); ifp_rename(&ifpdev, dest_file, temp); aifp_update_info(); aifp_directory_listing (NULL); } } gtk_widget_destroy(rename_dialog); } } void aifp_remove_item_cb (GtkButton *button, gpointer user_data) { gchar temp[MAXLEN]; gint response; if (strncmp(remote_item, PARENTDIR, 2)) { if (remote_type == TYPE_DIR) { sprintf(temp, _("Directory '%s' will be removed with its entire contents.\n\nDo you want to proceed?"), remote_item); } else { sprintf(temp, _("File '%s' will be removed.\n\nDo you want to proceed?"), remote_item); } response = message_dialog(_("Remove"), aifp_window, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, NULL, temp); if (response == GTK_RESPONSE_YES) { strncpy(temp, remote_path, MAXLEN-1); if (strlen(remote_path) != 1) { strncat(temp, "\\", MAXLEN-1); } strncat(temp, remote_item, MAXLEN-1); if (ifp_is_file (&ifpdev, temp) == TRUE) { ifp_delete (&ifpdev, temp); } else { ifp_delete_dir_recursive(&ifpdev, temp); } aifp_update_info(); aifp_check_size(); aifp_directory_listing (NULL); } } } void item_selected (GtkTreeModel *model, GtkTreeIter *iter, gpointer data) { gchar *text, *type; int * n = (int *)data; gtk_tree_model_get (model, iter, COLUMN_NAME, &text, COLUMN_TYPE_SIZE, &type, -1); strncpy(remote_item, text, MAXLEN-1); remote_type = TYPE_DIR; if(type != NULL) { if(strncmp(type, DIRID, strlen(DIRID))) { remote_type = TYPE_FILE; } if (n != NULL) { (*n)++; } } g_free(text); g_free(type); } gboolean multiple_items_selected_foreach_cb (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data) { item_selected (model, iter, (int *)data); return TRUE; } void directory_selected_cb (GtkTreeSelection *selection, gpointer data) { GtkTreeIter iter; GtkTreeModel *model; if (transfer_mode == UPLOAD_MODE) { if (gtk_tree_selection_get_selected (selection, &model, &iter)) { item_selected (model, &iter, NULL); } } else { number_of_songs = 0; gtk_tree_selection_selected_foreach(selection, (GtkTreeSelectionForeachFunc) multiple_items_selected_foreach_cb, &number_of_songs); } } gint aifp_dump_dir(void *context, int type, const char *name, int filesize) { GtkTreeIter iter; gint i = 0; if (type == IFP_DIR) { gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(list_store), &iter, NULL, i++); gtk_list_store_append(list_store, &iter); gtk_list_store_set(list_store, &iter, 0, name, 1, DIRID, -1); } return 0; } gint aifp_dump_files(void *context, int type, const char *name, int filesize) { GtkTreeIter iter; gchar temp[MAXLEN]; if (type == IFP_FILE) { gtk_list_store_append(list_store, &iter); sprintf(temp, "%.1f MB", (double)filesize/(1024*1024)); gtk_list_store_set(list_store, &iter, 0, name, 1, temp, -1); } return 0; } gint aifp_directory_listing(gchar *name) { GtkTreeIter iter; GtkTreePath *path; gint d = 0; gchar * item_name; gtk_list_store_clear(list_store); if (strlen(remote_path) != 1) { gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(list_store), &iter, NULL, 0); gtk_list_store_append(list_store, &iter); gtk_list_store_set(list_store, &iter, 0, PARENTDIR, -1); } if (ifp_list_dirs(&ifpdev, remote_path, aifp_dump_dir, NULL)) { fprintf(stderr, "ifp_device.c: aifp_directory_listing(): list dirs failed.\n"); return -1; } if (ifp_list_dirs(&ifpdev, remote_path, aifp_dump_files, NULL)) { fprintf(stderr, "ifp_device.c: aifp_directory_listing(): list dirs failed.\n"); return -1; } if (!name) { path = gtk_tree_path_new_first(); gtk_tree_view_set_cursor(GTK_TREE_VIEW(list), path, NULL, FALSE); g_free(path); } else { while(gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(list_store), &iter, NULL, d++)) { gtk_tree_model_get(GTK_TREE_MODEL(list_store), &iter, COLUMN_NAME, &item_name, -1); if (!strcmp(item_name, name)) { path = gtk_tree_path_new_from_indices (d-1, -1); gtk_tree_view_set_cursor(GTK_TREE_VIEW(list), path, NULL, FALSE); gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (list), path, NULL, TRUE, 0.5, 0.0); g_free(path); break; } } } return 0; } void aifp_update_info(void) { gchar temp[MAXLEN], tmp[MAXLEN]; gfloat space; if (transfer_mode == UPLOAD_MODE) { sprintf(temp, "%d", number_of_songs); sprintf(tmp, _(" (%.1f MB)"), (float)songs_size / (1024*1024)); strncat (temp, tmp, MAXLEN-1); gtk_label_set_text(GTK_LABEL(label_songs), temp); } battery_status = ifp_battery(&ifpdev); gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progressbar_battery), battery_status / 4.0); ifp_model(&ifpdev, temp, sizeof(temp)); capacity = ifp_capacity(&ifpdev); sprintf(tmp, _(" (capacity = %.1f MB)"), (float)capacity / (1024*1024)); strncat (temp, tmp, MAXLEN-1); gtk_label_set_text(GTK_LABEL(label_model), temp); freespace = ifp_freespace(&ifpdev); sprintf(temp, _(" Free space (%.1f MB)"), (float)freespace / (1024*1024)); space = (float)freespace/capacity; gtk_progress_bar_set_text (GTK_PROGRESS_BAR (progressbar_freespace), temp); gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progressbar_freespace), space); } int aifp_get_songs_info_foreach(playlist_t * pl, GtkTreeIter * iter, void * data) { struct stat statbuf; playlist_data_t * pldata; gint * num = (int *)data; gtk_tree_model_get(GTK_TREE_MODEL(pl->store), iter, PL_COL_DATA, &pldata, -1); if (g_stat(pldata->file, &statbuf) != -1) { songs_size += statbuf.st_size; (*num)++; } return 0; } gint aifp_get_number_of_songs(void) { gint num = 0; playlist_t * pl = playlist_get_current(); if (pl != NULL) { playlist_foreach_selected(pl, (void *)aifp_get_songs_info_foreach, &num); } return num; } int aifp_check_files_cb_foreach(playlist_t * pl, GtkTreeIter * iter, void * data) { struct stat statbuf; playlist_data_t * pldata; gtk_tree_model_get(GTK_TREE_MODEL(pl->store), iter, PL_COL_DATA, &pldata, -1); if (g_stat(pldata->file, &statbuf) != -1) { valid_files += is_valid_extension(valid_extensions_ifp, pldata->file, 0); } return 0; } gint aifp_check_files(void) { playlist_t * pl = playlist_get_current(); valid_files = 0; if (pl != NULL) { playlist_foreach_selected(pl, (void *)aifp_check_files_cb_foreach, NULL); } return valid_files; } void aifp_close_device(void) { if (ifp_finalize(&ifpdev)) { fprintf(stderr, "ifp_device.c: aifp_window_close(): finalize failed\n"); } usb_release_interface(dh, dev->config->interface->altsetting->bInterfaceNumber); if (ifp_release_device(dh)) { fprintf(stderr, "ifp_device.c: aifp_window_close(): release_device failed\n"); } } gint aifp_check_and_init_device(void) { usb_init(); dh = ifp_find_device(); if (dh == NULL) { message_dialog(_("Error"), options.playlist_is_embedded ? GTK_WIDGET(main_window) : GTK_WIDGET(playlist_window), GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, NULL, _("No suitable iRiver iFP device found.\n" "Perhaps it is unplugged or turned off.")); return -1; } dev = usb_device(dh); if (usb_claim_interface(dh, dev->config->interface->altsetting->bInterfaceNumber)) { message_dialog(_("Error"), options.playlist_is_embedded ? GTK_WIDGET(main_window) : GTK_WIDGET(playlist_window), GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, NULL, _("Device is busy.\n(Aqualung was unable to claim its interface.)")); if (ifp_release_device(dh)) { fprintf(stderr, "ifp_device.c: aifp_check_and_init_device(): release_device failed\n"); } return -1; } if (ifp_init(&ifpdev, dh)) { message_dialog(_("Error"), options.playlist_is_embedded ? GTK_WIDGET(main_window) : GTK_WIDGET(playlist_window), GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, NULL, _("Device is not responding.\nTry jiggling the handle.")); usb_release_interface(dh, dev->config->interface->altsetting->bInterfaceNumber); if (ifp_release_device(dh)) { fprintf(stderr, "ifp_device.c: aifp_check_and_init_device(): release_device failed\n"); } return -1; } return 0; } void aifp_check_size(void) { if (transfer_mode == UPLOAD_MODE) { if(songs_size > freespace) { gtk_widget_set_sensitive(upload_download_button, FALSE); } else { gtk_widget_set_sensitive(upload_download_button, TRUE); } } } gint aifp_window_key_pressed(GtkWidget * widget, GdkEventKey * kevent) { if (!transfer_active) { switch (kevent->keyval) { case GDK_Escape: aifp_window_close (NULL, NULL); return TRUE; case GDK_c: if (transfer_mode == UPLOAD_MODE) { aifp_create_directory_cb (NULL, NULL); return TRUE; } else { break; } case GDK_r: aifp_rename_item_cb (NULL, NULL); return TRUE; case GDK_Delete: case GDK_KP_Delete: aifp_remove_item_cb (NULL, NULL); return TRUE; } } return FALSE; } gint aifp_list_dbclick_cb(GtkWidget * widget, GdkEventButton * event, gpointer func_data) { gchar *npath; if ((event->type==GDK_2BUTTON_PRESS) && (event->button == 1)) { if (remote_type == TYPE_DIR) { if (!strncmp(remote_item, PARENTDIR, 2)) { npath = strrchr (remote_path, '\\'); if (npath != NULL) { *npath = '\0'; if (!strlen(remote_path)) { strcpy(remote_path, "\\"); } aifp_directory_listing(NULL); } } else { if (strlen(remote_path) != 1) { strcat(remote_path, "\\"); } strncat(remote_path, remote_item, MAXLEN-1); aifp_directory_listing(NULL); } } return TRUE; } return FALSE; } void directory_chooser(char * title, GtkWidget * parent, char * directory) { GtkWidget * dialog; const gchar * selected_directory; dialog = gtk_file_chooser_dialog_new(title, GTK_WINDOW(parent), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL); gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER); gtk_file_chooser_select_filename(GTK_FILE_CHOOSER(dialog), directory); gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT); if (options.show_hidden) { gtk_file_chooser_set_show_hidden(GTK_FILE_CHOOSER(dialog), TRUE); } if (aqualung_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { char * utf8; selected_directory = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); utf8 = g_filename_to_utf8(selected_directory, -1, NULL, NULL, NULL); if (utf8 == NULL) { gtk_widget_destroy(dialog); } strncpy(directory, selected_directory, MAXLEN-1); g_free(utf8); } gtk_widget_destroy(dialog); } void local_path_selected_cb(GtkButton * button, gpointer data) { directory_chooser(_("Please select a local path."), aifp_window, dest_dir); gtk_entry_set_text(GTK_ENTRY(local_path_entry), dest_dir); } void aifp_transfer_files(gint mode) { GtkWidget * vbox1; GtkWidget * vbox2; GtkWidget * vbox3; GtkWidget * vbox4; GtkWidget * hbox1; GtkWidget * hbox2; GtkWidget * alignment; GtkWidget * table; GtkWidget * label; GtkWidget * frame; GtkWidget * scrolledwindow; GtkWidget * hseparator; GtkWidget * vseparator; GtkWidget * hbuttonbox; GtkTreeSelection * list_selection; GtkCellRenderer * renderer; GtkTreeViewColumn * column; gchar temp[MAXLEN]; if (aifp_window != NULL) { return; } transfer_mode = mode; songs_size = 0; transfer_active = 0; strcpy(remote_path, "\\"); if (transfer_mode == UPLOAD_MODE) { number_of_songs = aifp_get_number_of_songs(); if (!number_of_songs) { message_dialog(_("Warning"), options.playlist_is_embedded ? GTK_WIDGET(main_window) : GTK_WIDGET(playlist_window), GTK_MESSAGE_WARNING, GTK_BUTTONS_CLOSE, NULL, _("Please select at least one valid song from playlist.")); return; } } if (aifp_check_and_init_device() == -1) { return; } if (transfer_mode == UPLOAD_MODE) { gint k = aifp_check_files(); if (k != number_of_songs) { if (k) { if((number_of_songs-k) == 1) { sprintf(temp, _("One song has format unsupported by your player.\n\nDo you want to proceed?")); } else { sprintf(temp, _("%d of %d songs have format unsupported by your player.\n\nDo you want to proceed?"), number_of_songs-k, number_of_songs); } } else { if (number_of_songs == 1) { sprintf(temp, _("The selected song has format unsupported by your player.\n\nDo you want to proceed?")); } else { sprintf(temp, _("None of the selected songs has format supported by your player.\n\nDo you want to proceed?")); } } gint ret = message_dialog(_("Warning"), options.playlist_is_embedded ? GTK_WIDGET(main_window) : GTK_WIDGET(playlist_window), GTK_MESSAGE_WARNING, GTK_BUTTONS_YES_NO, NULL, temp); if (ret == GTK_RESPONSE_NO || ret == GTK_RESPONSE_DELETE_EVENT) { aifp_close_device(); return; } } } aifp_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); if (transfer_mode == UPLOAD_MODE) { gtk_window_set_title(GTK_WINDOW(aifp_window), _("iFP device manager (upload mode)")); } else { gtk_window_set_title(GTK_WINDOW(aifp_window), _("iFP device manager (download mode)")); } gtk_window_set_position(GTK_WINDOW(aifp_window), GTK_WIN_POS_CENTER_ALWAYS); gtk_window_set_transient_for(GTK_WINDOW(aifp_window), options.playlist_is_embedded ? GTK_WINDOW(main_window) : GTK_WINDOW(playlist_window)); gtk_window_set_modal(GTK_WINDOW(aifp_window), TRUE); g_signal_connect(G_OBJECT(aifp_window), "delete_event", G_CALLBACK(aifp_window_close), NULL); g_signal_connect(G_OBJECT(aifp_window), "key_press_event", G_CALLBACK(aifp_window_key_pressed), NULL); gtk_container_set_border_width(GTK_CONTAINER(aifp_window), 5); gtk_window_set_default_size(GTK_WINDOW(aifp_window), options.ifpmanager_size_x, options.ifpmanager_size_y); vbox1 = gtk_vbox_new (FALSE, 0); gtk_widget_show (vbox1); gtk_container_add (GTK_CONTAINER (aifp_window), vbox1); vbox2 = gtk_vbox_new (FALSE, 0); gtk_widget_show (vbox2); gtk_box_pack_start (GTK_BOX (vbox1), vbox2, TRUE, TRUE, 0); frame = gtk_frame_new (NULL); gtk_widget_show (frame); gtk_box_pack_start (GTK_BOX (vbox2), frame, FALSE, FALSE, 0); gtk_container_set_border_width (GTK_CONTAINER (frame), 2); gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE); alignment = gtk_alignment_new (0.5, 0.5, 1, 1); gtk_widget_show (alignment); gtk_container_add (GTK_CONTAINER (frame), alignment); gtk_container_set_border_width (GTK_CONTAINER (alignment), 4); gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 0, 12, 0); if (transfer_mode == UPLOAD_MODE) { hbox1 = gtk_hbox_new (FALSE, 0); gtk_widget_show (hbox1); gtk_container_add (GTK_CONTAINER (alignment), hbox1); label = gtk_label_new (_("Selected files:")); gtk_widget_show (label); gtk_box_pack_start (GTK_BOX (hbox1), label, FALSE, FALSE, 0); gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); label_songs = gtk_label_new ("label_songs"); gtk_widget_show (label_songs); gtk_box_pack_start (GTK_BOX (hbox1), label_songs, FALSE, FALSE, 0); gtk_misc_set_alignment (GTK_MISC (label_songs), 0, 0.5); gtk_misc_set_padding (GTK_MISC (label_songs), 5, 0); label = gtk_label_new (_("Songs info")); gtk_widget_show (label); gtk_frame_set_label_widget (GTK_FRAME (frame), label); gtk_label_set_use_markup (GTK_LABEL (label), TRUE); frame = gtk_frame_new (NULL); gtk_widget_show (frame); gtk_box_pack_start (GTK_BOX (vbox2), frame, FALSE, FALSE, 0); gtk_container_set_border_width (GTK_CONTAINER (frame), 2); gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE); alignment = gtk_alignment_new (0.5, 0.5, 1, 1); gtk_widget_show (alignment); gtk_container_add (GTK_CONTAINER (frame), alignment); gtk_container_set_border_width (GTK_CONTAINER (alignment), 4); gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 0, 12, 0); } vbox3 = gtk_vbox_new (FALSE, 0); gtk_widget_show (vbox3); gtk_container_add (GTK_CONTAINER (alignment), vbox3); hbox1 = gtk_hbox_new (FALSE, 0); gtk_widget_show (hbox1); gtk_box_pack_start (GTK_BOX (vbox3), hbox1, TRUE, TRUE, 2); label = gtk_label_new (_("Model:")); gtk_widget_show (label); gtk_box_pack_start (GTK_BOX (hbox1), label, FALSE, FALSE, 0); gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); label_model = gtk_label_new (NULL); gtk_widget_show (label_model); gtk_box_pack_start (GTK_BOX (hbox1), label_model, FALSE, FALSE, 0); gtk_misc_set_alignment (GTK_MISC (label_model), 0, 0.5); gtk_misc_set_padding (GTK_MISC (label_model), 5, 0); hbox1 = gtk_hbox_new (FALSE, 0); gtk_widget_show (hbox1); gtk_box_pack_start (GTK_BOX (vbox3), hbox1, TRUE, TRUE, 2); progressbar_battery = gtk_progress_bar_new (); gtk_widget_show (progressbar_battery); gtk_box_pack_start (GTK_BOX (hbox1), progressbar_battery, TRUE, TRUE, 2); gtk_widget_set_size_request (progressbar_battery, 70, -1); gtk_progress_bar_set_text (GTK_PROGRESS_BAR (progressbar_battery), _("Battery")); progressbar_freespace = gtk_progress_bar_new (); gtk_widget_show (progressbar_freespace); gtk_box_pack_start (GTK_BOX (hbox1), progressbar_freespace, TRUE, TRUE, 2); gtk_progress_bar_set_text (GTK_PROGRESS_BAR (progressbar_freespace), _("Free space")); label = gtk_label_new (_("Device status")); gtk_widget_show (label); gtk_frame_set_label_widget (GTK_FRAME (frame), label); gtk_label_set_use_markup (GTK_LABEL (label), TRUE); frame = gtk_frame_new (NULL); gtk_widget_show (frame); gtk_box_pack_start (GTK_BOX (vbox2), frame, TRUE, TRUE, 0); gtk_container_set_border_width (GTK_CONTAINER (frame), 2); gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE); alignment = gtk_alignment_new (0.5, 0.5, 1, 1); gtk_widget_show (alignment); gtk_container_add (GTK_CONTAINER (frame), alignment); gtk_container_set_border_width (GTK_CONTAINER (alignment), 4); gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 0, 12, 0); hbox1 = gtk_hbox_new (FALSE, 0); gtk_widget_show (hbox1); gtk_container_add (GTK_CONTAINER (alignment), hbox1); scrolledwindow = gtk_scrolled_window_new (NULL, NULL); gtk_widget_show (scrolledwindow); gtk_box_pack_start (GTK_BOX (hbox1), scrolledwindow, TRUE, TRUE, 0); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow), GTK_SHADOW_IN); list_store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING); list = gtk_tree_view_new_with_model(GTK_TREE_MODEL(list_store)); gtk_widget_show (list); g_signal_connect(G_OBJECT(list), "button_press_event", G_CALLBACK(aifp_list_dbclick_cb), NULL); list_selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (list)); g_signal_connect(G_OBJECT(list_selection), "changed", G_CALLBACK(directory_selected_cb), NULL); gtk_container_add (GTK_CONTAINER (scrolledwindow), list); gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(list), TRUE); gtk_tree_view_set_enable_search (GTK_TREE_VIEW(list), FALSE); if (transfer_mode == DOWNLOAD_MODE) { gtk_tree_selection_set_mode(list_selection, GTK_SELECTION_MULTIPLE); } renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes(_("Name"), renderer, "text", COLUMN_NAME, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(list), column); gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE); renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes(_("Size"), renderer, "text", COLUMN_TYPE_SIZE, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(list), column); gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE); vseparator = gtk_vseparator_new (); gtk_widget_show (vseparator); gtk_box_pack_start (GTK_BOX (hbox1), vseparator, FALSE, TRUE, 2); vbox4 = gtk_vbox_new (FALSE, 0); gtk_widget_show (vbox4); gtk_box_pack_start (GTK_BOX (hbox1), vbox4, FALSE, FALSE, 0); if (transfer_mode == UPLOAD_MODE) { mkdir_button = gui_stock_label_button(NULL, GTK_STOCK_NEW); gtk_button_set_relief (GTK_BUTTON (mkdir_button), GTK_RELIEF_NONE); GTK_WIDGET_UNSET_FLAGS(mkdir_button, GTK_CAN_FOCUS); gtk_widget_show (mkdir_button); g_signal_connect(mkdir_button, "clicked", G_CALLBACK(aifp_create_directory_cb), NULL); gtk_box_pack_start (GTK_BOX (vbox4), mkdir_button, FALSE, FALSE, 0); } rndir_button = gui_stock_label_button(NULL, GTK_STOCK_EDIT); GTK_WIDGET_UNSET_FLAGS(rndir_button, GTK_CAN_FOCUS); gtk_button_set_relief (GTK_BUTTON (rndir_button), GTK_RELIEF_NONE); gtk_widget_show (rndir_button); g_signal_connect(rndir_button, "clicked", G_CALLBACK(aifp_rename_item_cb), NULL); gtk_box_pack_start (GTK_BOX (vbox4), rndir_button, FALSE, FALSE, 0); rmdir_button = gui_stock_label_button(NULL, GTK_STOCK_DELETE); GTK_WIDGET_UNSET_FLAGS(rmdir_button, GTK_CAN_FOCUS); gtk_button_set_relief (GTK_BUTTON (rmdir_button), GTK_RELIEF_NONE); gtk_widget_show (rmdir_button); g_signal_connect(rmdir_button, "clicked", G_CALLBACK(aifp_remove_item_cb), NULL); gtk_box_pack_start (GTK_BOX (vbox4), rmdir_button, FALSE, FALSE, 0); if (options.enable_tooltips) { if (transfer_mode == UPLOAD_MODE) { aqualung_widget_set_tooltip_text(mkdir_button, _("Create a new directory")); } aqualung_widget_set_tooltip_text(rndir_button, _("Rename")); aqualung_widget_set_tooltip_text(rmdir_button, _("Remove")); } label = gtk_label_new (_("Remote directory")); gtk_widget_show (label); gtk_frame_set_label_widget (GTK_FRAME (frame), label); gtk_label_set_use_markup (GTK_LABEL (label), TRUE); frame = gtk_frame_new (NULL); gtk_widget_show (frame); gtk_box_pack_start (GTK_BOX (vbox2), frame, FALSE, FALSE, 0); gtk_container_set_border_width (GTK_CONTAINER (frame), 2); gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE); if (transfer_mode == DOWNLOAD_MODE) { label = gtk_label_new (_("Local directory")); gtk_widget_show (label); gtk_frame_set_label_widget (GTK_FRAME (frame), label); gtk_label_set_use_markup (GTK_LABEL (label), TRUE); frame = gtk_frame_new (NULL); gtk_widget_show (frame); gtk_box_pack_start (GTK_BOX (vbox2), frame, FALSE, FALSE, 0); gtk_container_set_border_width (GTK_CONTAINER (frame), 2); gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE); alignment = gtk_alignment_new (0.5, 0.5, 1, 1); gtk_widget_show (alignment); gtk_container_add (GTK_CONTAINER (frame), alignment); gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 0, 12, 0); hbox2 = gtk_hbox_new(FALSE, FALSE); gtk_container_add (GTK_CONTAINER (alignment), hbox2); gtk_widget_show (hbox2); local_path_entry = gtk_entry_new(); gtk_widget_show (local_path_entry); GTK_WIDGET_UNSET_FLAGS(local_path_entry, GTK_CAN_FOCUS); gtk_box_pack_start(GTK_BOX(hbox2), local_path_entry, TRUE, TRUE, 2); gtk_editable_set_editable (GTK_EDITABLE(local_path_entry), FALSE); strncpy(dest_dir, options.home, MAXLEN-1); gtk_entry_set_text(GTK_ENTRY(local_path_entry), dest_dir); local_path_browse_button = gui_stock_label_button(_("Browse"), GTK_STOCK_OPEN); GTK_WIDGET_UNSET_FLAGS(local_path_browse_button, GTK_CAN_FOCUS); gtk_widget_show (local_path_browse_button); gtk_container_set_border_width(GTK_CONTAINER(local_path_browse_button), 2); g_signal_connect (G_OBJECT(local_path_browse_button), "clicked", G_CALLBACK(local_path_selected_cb), (gpointer)local_path_entry); gtk_box_pack_end(GTK_BOX(hbox2), local_path_browse_button, FALSE, FALSE, 0); } frame = gtk_frame_new (NULL); gtk_widget_show (frame); gtk_box_pack_start (GTK_BOX (vbox2), frame, FALSE, FALSE, 0); gtk_container_set_border_width (GTK_CONTAINER (frame), 2); gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE); alignment = gtk_alignment_new (0.5, 0.5, 1, 1); gtk_widget_show (alignment); gtk_container_add (GTK_CONTAINER (frame), alignment); gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 0, 12, 0); table = gtk_table_new (3, 2, FALSE); gtk_widget_show (table); gtk_container_add (GTK_CONTAINER (alignment), table); gtk_container_set_border_width (GTK_CONTAINER (table), 8); gtk_table_set_row_spacings (GTK_TABLE (table), 4); gtk_table_set_col_spacings (GTK_TABLE (table), 4); label = gtk_label_new (_("File name: ")); gtk_widget_show (label); gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); label = gtk_label_new (_("Current file: ")); gtk_widget_show (label); gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); label = gtk_label_new (_("Overall: ")); gtk_widget_show (label); gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); aifp_file_entry = gtk_entry_new(); GTK_WIDGET_UNSET_FLAGS(aifp_file_entry, GTK_CAN_FOCUS); gtk_widget_show (aifp_file_entry); gtk_editable_set_editable(GTK_EDITABLE(aifp_file_entry), FALSE); gtk_table_attach (GTK_TABLE (table), aifp_file_entry, 1, 2, 0, 1, (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), (GtkAttachOptions) (0), 0, 0); gtk_entry_set_text(GTK_ENTRY(aifp_file_entry), _("None")); progressbar_cf = gtk_progress_bar_new (); gtk_widget_show (progressbar_cf); gtk_progress_bar_set_text (GTK_PROGRESS_BAR (progressbar_cf), _("Idle")); gtk_table_attach (GTK_TABLE (table), progressbar_cf, 1, 2, 1, 2, (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), (GtkAttachOptions) (0), 0, 0); progressbar_op = gtk_progress_bar_new (); gtk_widget_show (progressbar_op); gtk_progress_bar_set_text (GTK_PROGRESS_BAR (progressbar_op), _("Idle")); gtk_table_attach (GTK_TABLE (table), progressbar_op, 1, 2, 2, 3, (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), (GtkAttachOptions) (0), 0, 0); label = gtk_label_new (_("Transfer progress")); gtk_widget_show (label); gtk_frame_set_label_widget (GTK_FRAME (frame), label); gtk_label_set_use_markup (GTK_LABEL (label), TRUE); aifp_close_when_ready_check = gtk_check_button_new_with_label(_("Close window when transfer complete")); GTK_WIDGET_UNSET_FLAGS(aifp_close_when_ready_check, GTK_CAN_FOCUS); gtk_widget_set_name(aifp_close_when_ready_check, "check_on_window"); gtk_widget_show(aifp_close_when_ready_check); gtk_box_pack_start(GTK_BOX(vbox2), aifp_close_when_ready_check, FALSE, TRUE, 0); hseparator = gtk_hseparator_new (); gtk_widget_show (hseparator); gtk_box_pack_start (GTK_BOX (vbox1), hseparator, FALSE, TRUE, 3); hbuttonbox = gtk_hbutton_box_new (); gtk_widget_show (hbuttonbox); gtk_box_pack_start (GTK_BOX (vbox1), hbuttonbox, FALSE, TRUE, 0); gtk_container_set_border_width (GTK_CONTAINER (hbuttonbox), 5); gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox), GTK_BUTTONBOX_END); gtk_box_set_spacing (GTK_BOX (hbuttonbox), 6); if (transfer_mode == UPLOAD_MODE) { upload_download_button = gui_stock_label_button (_("_Upload"), GTK_STOCK_GO_UP); } else { upload_download_button = gui_stock_label_button (_("_Download"), GTK_STOCK_GO_DOWN); } GTK_WIDGET_UNSET_FLAGS(upload_download_button, GTK_CAN_FOCUS); gtk_widget_show (upload_download_button); g_signal_connect(upload_download_button, "clicked", G_CALLBACK(upload_download_songs_cb), NULL); gtk_container_add (GTK_CONTAINER (hbuttonbox), upload_download_button); GTK_WIDGET_SET_FLAGS (upload_download_button, GTK_CAN_DEFAULT); abort_button = gui_stock_label_button (_("_Abort"), GTK_STOCK_CANCEL); GTK_WIDGET_UNSET_FLAGS(abort_button, GTK_CAN_FOCUS); gtk_widget_show (abort_button); g_signal_connect(abort_button, "clicked", G_CALLBACK(abort_transfer_cb), NULL); gtk_container_add (GTK_CONTAINER (hbuttonbox), abort_button); GTK_WIDGET_SET_FLAGS (abort_button, GTK_CAN_DEFAULT); close_button = gtk_button_new_from_stock (GTK_STOCK_CLOSE); GTK_WIDGET_UNSET_FLAGS(close_button, GTK_CAN_FOCUS); gtk_widget_show (close_button); g_signal_connect(close_button, "clicked", G_CALLBACK(aifp_window_close), NULL); gtk_container_add (GTK_CONTAINER (hbuttonbox), close_button); GTK_WIDGET_SET_FLAGS (close_button, GTK_CAN_DEFAULT); gtk_widget_set_sensitive(abort_button, FALSE); gtk_widget_grab_focus(list); aifp_update_info(); aifp_directory_listing (NULL); aifp_check_size(); abort_pressed = 0; remote_type = TYPE_DIR; gtk_widget_show(aifp_window); } #endif /* HAVE_IFP */ // vim: shiftwidth=8:tabstop=8:softtabstop=8: aqualung-0.9beta11/src/loop_bar.h0000644000175000001440000000443711136163152013656 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: loop_bar.h 1045 2008-12-25 13:10:34Z peterszilagyi $ */ #ifndef _LOOP_BAR_H #define _LOOP_BAR_H #include #ifdef HAVE_LOOP #include G_BEGIN_DECLS #define AQUALUNG_TYPE_LOOP_BAR (aqualung_loop_bar_get_type ()) #define AQUALUNG_LOOP_BAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), AQUALUNG_TYPE_LOOP_BAR, AqualungLoopBar)) #define AQUALUNG_LOOP_BAR_CLASS(obj) (G_TYPE_CHECK_CLASS_CAST ((obj), AQUALUNG_LOOP_BAR, AqualungLoopBarClass)) #define AQUALUNG_IS_LOOP_BAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), AQUALUNG_TYPE_LOOP_BAR)) #define AQUALUNG_IS_LOOP_BAR_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE ((obj), AQUALUNG_TYPE_LOOP_BAR)) #define AQUALUNG_LOOP_BAR_GET_CLASS (G_TYPE_INSTANCE_GET_CLASS ((obj), AQUALUNG_TYPE_LOOP_BAR, AqualungLoopBarClass)) typedef struct _AqualungLoopBar AqualungLoopBar; typedef struct _AqualungLoopBarClass AqualungLoopBarClass; struct _AqualungLoopBar { GtkDrawingArea parent; }; struct _AqualungLoopBarClass { GtkDrawingAreaClass parent_class; void (* range_changed) (AqualungLoopBar * bar, float start, float end); }; GType aqualung_loop_bar_get_type(void) G_GNUC_CONST; GtkWidget * aqualung_loop_bar_new(float start, float end); void aqualung_loop_bar_adjust_start(AqualungLoopBar * bar, float start); void aqualung_loop_bar_adjust_end(AqualungLoopBar * bar, float end); G_END_DECLS #endif /* HAVE_LOOP */ #endif /* _LOOP_BAR_H */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/loop_bar.c0000644000175000001440000002771311136163537013662 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: loop_bar.c 1045 2008-12-25 13:10:34Z peterszilagyi $ */ #include #ifdef HAVE_LOOP #include #include "loop_bar.h" #define AQUALUNG_LOOP_BAR_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), AQUALUNG_TYPE_LOOP_BAR, AqualungLoopBarPrivate)) G_DEFINE_TYPE (AqualungLoopBar, aqualung_loop_bar, GTK_TYPE_DRAWING_AREA); typedef struct _AqualungLoopBarPrivate AqualungLoopBarPrivate; struct _AqualungLoopBarPrivate { float start; float end; gboolean start_dragged; gboolean end_dragged; gboolean start_hover; gboolean end_hover; gint prev_x; gint width; gint margin; }; enum { RANGE_CHANGED, LAST_SIGNAL }; static guint aqualung_loop_bar_signals[LAST_SIGNAL] = { 0 }; void _loop_bar_marshal_VOID__FLOAT_FLOAT(GClosure * closure, GValue * return_value, guint n_param_values, const GValue * param_values, gpointer invocation_hint, gpointer marshal_data) { typedef void (* GMarshalFunc_VOID__FLOAT_FLOAT) (gpointer data1, gfloat arg_1, gfloat arg_2, gpointer data2); GMarshalFunc_VOID__FLOAT_FLOAT callback; GCClosure * cc = (GCClosure *)closure; gpointer data1, data2; g_return_if_fail(n_param_values == 3); if (G_CCLOSURE_SWAP_DATA(closure)) { data1 = closure->data; data2 = g_value_peek_pointer(param_values + 0); } else { data1 = g_value_peek_pointer(param_values + 0); data2 = closure->data; } callback = (GMarshalFunc_VOID__FLOAT_FLOAT) (marshal_data ? marshal_data : cc->callback); callback(data1, g_value_get_float(param_values + 1), g_value_get_float(param_values + 2), data2); } void aqualung_loop_bar_draw_marker(GtkWidget * widget, cairo_t * cr, int x, int height, gboolean hover) { AqualungLoopBarPrivate * priv = AQUALUNG_LOOP_BAR_GET_PRIVATE(widget); GdkColor fg = widget->style->fg[hover ? GTK_STATE_PRELIGHT : GTK_STATE_NORMAL]; double fg_r = fg.red / 65535.0; double fg_g = fg.green / 65535.0; double fg_b = fg.blue / 65535.0; cairo_new_path(cr); cairo_move_to(cr, x - priv->width, 0); cairo_rel_line_to(cr, 2 * priv->width, 0); cairo_rel_line_to(cr, 0, height / 2); cairo_rel_line_to(cr, -priv->width, height / 2); cairo_rel_line_to(cr, -priv->width, -height / 2); cairo_rel_line_to(cr, 0, -height / 2); cairo_close_path(cr); cairo_set_source_rgb(cr, fg_r, fg_g, fg_b); cairo_fill_preserve(cr); cairo_set_source_rgb(cr, fg_r / 2, fg_g / 2, fg_b / 2); cairo_stroke(cr); } gboolean aqualung_loop_bar_expose(GtkWidget * widget, GdkEventExpose * event) { cairo_t * cr; int x_start; int x_end; int height; GdkColor bg = widget->style->bg[GTK_STATE_SELECTED]; GdkColor bg2 = widget->style->bg[GTK_STATE_ACTIVE]; double bg_r = bg.red / 65535.0; double bg_g = bg.green / 65535.0; double bg_b = bg.blue / 65535.0; double bg2_r = bg2.red / 65535.0; double bg2_g = bg2.green / 65535.0; double bg2_b = bg2.blue / 65535.0; AqualungLoopBarPrivate * priv = AQUALUNG_LOOP_BAR_GET_PRIVATE(widget); x_start = (widget->allocation.width - 2 * priv->margin) * priv->start + priv->margin; x_end = (widget->allocation.width - 2 * priv->margin) * priv->end + priv->margin; height = widget->allocation.height; cr = gdk_cairo_create(widget->window); cairo_rectangle(cr, event->area.x, event->area.y, event->area.width, event->area.height); cairo_clip(cr); cairo_set_line_width(cr, 1.0); cairo_new_path(cr); cairo_rectangle(cr, x_start, 0, x_end - x_start, height); cairo_set_source_rgb(cr, bg_r, bg_g, bg_b); cairo_fill_preserve(cr); aqualung_loop_bar_draw_marker(widget, cr, x_end, height, priv->end_hover); aqualung_loop_bar_draw_marker(widget, cr, x_start, height, priv->start_hover); cairo_new_path(cr); cairo_move_to(cr, 0, height); cairo_rel_line_to(cr, 0, -height); cairo_rel_line_to(cr, widget->allocation.width, 0); cairo_set_source_rgb(cr, bg2_r, bg2_g, bg2_b); cairo_stroke(cr); cairo_new_path(cr); cairo_move_to(cr, 0, height); cairo_rel_line_to(cr, widget->allocation.width, 0); cairo_rel_line_to(cr, 0, -height); cairo_set_source_rgb(cr, bg2_r * 2, bg2_g * 2, bg2_b * 2); cairo_stroke(cr); cairo_destroy(cr); return FALSE; } void aqualung_loop_bar_redraw_canvas(GtkWidget * widget) { GdkRegion *region; if (!widget->window) { return; } region = gdk_drawable_get_clip_region(widget->window); gdk_window_invalidate_region(widget->window, region, TRUE); gdk_window_process_updates(widget->window, TRUE); gdk_region_destroy(region); } void aqualung_loop_bar_update(GtkWidget * widget, int x) { AqualungLoopBarPrivate * priv = AQUALUNG_LOOP_BAR_GET_PRIVATE(widget); gboolean redraw = FALSE; if (priv->start_dragged || (!priv->end_dragged && x >= (widget->allocation.width - 2 * priv->margin) * priv->start + priv->margin - priv->width && x <= (widget->allocation.width - 2 * priv->margin) * priv->start + priv->margin + priv->width)) { if (priv->start_hover == FALSE) { priv->start_hover = TRUE; priv->end_hover = FALSE; redraw = TRUE; } } else { if (priv->start_hover == TRUE) { priv->start_hover = FALSE; redraw = TRUE; } } if (priv->end_dragged || (!priv->start_dragged && x >= (widget->allocation.width - 2 * priv->margin) * priv->end + priv->margin - priv->width && x <= (widget->allocation.width - 2 * priv->margin) * priv->end + priv->margin + priv->width)) { if (priv->end_hover == FALSE && priv->start_hover == FALSE) { priv->end_hover = TRUE; redraw = TRUE; } } else { if (priv->end_hover == TRUE) { priv->end_hover = FALSE; redraw = TRUE; } } if (priv->start_dragged) { priv->start += (float)(x - priv->prev_x) / (widget->allocation.width - 2 * priv->margin); priv->start = priv->start < 0 ? 0 : priv->start; priv->start = priv->start > priv->end ? priv->end : priv->start; priv->prev_x = x; redraw = TRUE; } else if (priv->end_dragged) { priv->end += (float)(x - priv->prev_x) / (widget->allocation.width - 2 * priv->margin); priv->end = priv->end < priv->start ? priv->start : priv->end; priv->end = priv->end > 1 ? 1 : priv->end; priv->prev_x = x; redraw = TRUE; } if (redraw) { aqualung_loop_bar_redraw_canvas(widget); } } gboolean aqualung_loop_bar_motion_notify(GtkWidget * widget, GdkEventMotion * event) { aqualung_loop_bar_update(widget, event->x); return FALSE; } gboolean aqualung_loop_bar_button_press(GtkWidget * widget, GdkEventButton * event) { AqualungLoopBarPrivate * priv = AQUALUNG_LOOP_BAR_GET_PRIVATE(widget); if (event->state & GDK_SHIFT_MASK) { /* SHIFT */ priv->start = 0.0f; priv->end = 1.0f; aqualung_loop_bar_redraw_canvas(widget); return TRUE; } if (event->button == 1) { priv->prev_x = event->x; if (event->x >= (widget->allocation.width - 2 * priv->margin) * priv->start + priv->margin - priv->width && event->x <= (widget->allocation.width - 2 * priv->margin) * priv->start + priv->margin + priv->width) { priv->start_dragged = TRUE; } else if (event->x >= (widget->allocation.width - 2 * priv->margin) * priv->end + priv->margin - priv->width && event->x <= (widget->allocation.width - 2 * priv->margin) * priv->end + priv->margin + priv->width) { priv->end_dragged = TRUE; } } return FALSE; } gboolean aqualung_loop_bar_button_release(GtkWidget * widget, GdkEventButton * event) { AqualungLoopBarPrivate * priv = AQUALUNG_LOOP_BAR_GET_PRIVATE(widget); priv->start_dragged = FALSE; priv->end_dragged = FALSE; aqualung_loop_bar_update(widget, event->x); g_signal_emit(widget, aqualung_loop_bar_signals[RANGE_CHANGED], 0, priv->start, priv->end); return FALSE; } gboolean aqualung_loop_bar_enter_notify(GtkWidget * widget, GdkEventCrossing * event) { aqualung_loop_bar_update(widget, event->x); return FALSE; } gboolean aqualung_loop_bar_leave_notify(GtkWidget * widget, GdkEventCrossing * event) { AqualungLoopBarPrivate * priv; if (event->y >= 0 && event->y < widget->allocation.height && event->x >= 0 && event->x < widget->allocation.width) { /* before each button press event we receive a leave * notify event, which should be neglected. */ return FALSE; } priv = AQUALUNG_LOOP_BAR_GET_PRIVATE(widget); priv->start_hover = priv->start_dragged; priv->end_hover = priv->end_dragged; aqualung_loop_bar_redraw_canvas(widget); return FALSE; } void aqualung_loop_bar_class_init(AqualungLoopBarClass * class) { GObjectClass * obj_class; GtkWidgetClass * widget_class; obj_class = G_OBJECT_CLASS(class); widget_class = GTK_WIDGET_CLASS(class); aqualung_loop_bar_signals[RANGE_CHANGED] = g_signal_new ( "range-changed", G_OBJECT_CLASS_TYPE(obj_class), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET(AqualungLoopBarClass, range_changed), NULL, NULL, _loop_bar_marshal_VOID__FLOAT_FLOAT, G_TYPE_NONE, 2, G_TYPE_FLOAT, G_TYPE_FLOAT); widget_class->expose_event = aqualung_loop_bar_expose; widget_class->button_press_event = aqualung_loop_bar_button_press; widget_class->button_release_event = aqualung_loop_bar_button_release; widget_class->motion_notify_event = aqualung_loop_bar_motion_notify; widget_class->enter_notify_event = aqualung_loop_bar_enter_notify; widget_class->leave_notify_event = aqualung_loop_bar_leave_notify; g_type_class_add_private(obj_class, sizeof(AqualungLoopBarPrivate)); } void aqualung_loop_bar_init(AqualungLoopBar * bar) { AqualungLoopBarPrivate * priv = AQUALUNG_LOOP_BAR_GET_PRIVATE(bar); priv->start = 0.0f; priv->end = 1.0f; priv->start_dragged = FALSE; priv->end_dragged = FALSE; priv->start_hover = FALSE; priv->end_hover = FALSE; priv->width = 4; priv->margin = 16; gtk_widget_add_events(GTK_WIDGET(bar), GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK); } GtkWidget * aqualung_loop_bar_new(float start, float end) { GtkWidget * widget; AqualungLoopBarPrivate * priv; widget = g_object_new(AQUALUNG_TYPE_LOOP_BAR, NULL); priv = AQUALUNG_LOOP_BAR_GET_PRIVATE(AQUALUNG_LOOP_BAR(widget)); priv->start = start; priv->end = end; return widget; } void aqualung_loop_bar_adjust_start(AqualungLoopBar * bar, float start) { AqualungLoopBarPrivate * priv = AQUALUNG_LOOP_BAR_GET_PRIVATE(bar); if (start < priv->end) { priv->start = start; aqualung_loop_bar_redraw_canvas(GTK_WIDGET(bar)); g_signal_emit(GTK_WIDGET(bar), aqualung_loop_bar_signals[RANGE_CHANGED], 0, priv->start, priv->end); } } void aqualung_loop_bar_adjust_end(AqualungLoopBar * bar, float end) { AqualungLoopBarPrivate * priv = AQUALUNG_LOOP_BAR_GET_PRIVATE(bar); if (end > priv->start) { priv->end = end; aqualung_loop_bar_redraw_canvas(GTK_WIDGET(bar)); g_signal_emit(GTK_WIDGET(bar), aqualung_loop_bar_signals[RANGE_CHANGED], 0, priv->start, priv->end); } } #endif /* HAVE_LOOP */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/metadata.h0000644000175000001440000002164110735145160013640 00000000000000/* -*- linux-c -*- Copyright (C) 2007 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: metadata.h 966 2007-12-27 23:36:08Z peterszilagyi $ */ #ifndef _METADATA_H #define _METADATA_H #include #include #include "common.h" /* tag (and pseudo-tag) types */ #define META_TAG_NULL 0x000 #define META_TAG_ID3v1 0x001 #define META_TAG_ID3v2 0x002 #define META_TAG_APE 0x004 #define META_TAG_OXC 0x008 #define META_TAG_FLAC_APIC 0x010 #define META_TAG_MPC_RGDATA 0x020 #define META_TAG_GEN_STREAM 0x040 #define META_TAG_MPEGSTREAM 0x080 #define META_TAG_MODINFO 0x100 #define META_TAG_MAX 0x100 #define META_N_TAGS 8 /* NULL and MODINFO are pseudo-tags */ /* frame types -- string, integer, float, binary */ /* string types (most basic ones) */ #define META_FIELD_TITLE 0x01 #define META_FIELD_ARTIST 0x02 #define META_FIELD_ALBUM 0x03 #define META_FIELD_DATE 0x04 #define META_FIELD_GENRE 0x05 #define META_FIELD_COMMENT 0x06 /* string types added for OXC */ #define META_FIELD_PERFORMER 0x07 #define META_FIELD_DESCRIPTION 0x08 #define META_FIELD_ORGANIZATION 0x09 #define META_FIELD_LOCATION 0x0a #define META_FIELD_CONTACT 0x0b #define META_FIELD_LICENSE 0x0c #define META_FIELD_COPYRIGHT 0x0d #define META_FIELD_ISRC 0x0e #define META_FIELD_VERSION 0x0f /* string types added for APE */ #define META_FIELD_SUBTITLE 0x10 #define META_FIELD_DEBUT_ALBUM 0x11 #define META_FIELD_PUBLISHER 0x12 #define META_FIELD_CONDUCTOR 0x13 #define META_FIELD_COMPOSER 0x14 #define META_FIELD_PRIGHT 0x15 #define META_FIELD_FILE 0x16 #define META_FIELD_ISBN 0x17 #define META_FIELD_CATALOG 0x18 #define META_FIELD_LC 0x19 #define META_FIELD_RECORD_DATE 0x1a #define META_FIELD_RECORD_LOC 0x1b #define META_FIELD_MEDIA 0x1c #define META_FIELD_INDEX 0x1d #define META_FIELD_RELATED 0x1e #define META_FIELD_ABSTRACT 0x1f #define META_FIELD_LANGUAGE 0x20 #define META_FIELD_BIBLIOGRAPHY 0x21 #define META_FIELD_INTROPLAY 0x22 /* string types added for ID3v2 */ #define META_FIELD_TBPM 0x30 #define META_FIELD_TDEN 0x31 #define META_FIELD_TDLY 0x32 #define META_FIELD_TDOR 0x33 #define META_FIELD_TDRL 0x34 #define META_FIELD_TDTG 0x35 #define META_FIELD_TENC 0x36 #define META_FIELD_T_E_X_T 0x37 #define META_FIELD_TFLT 0x38 #define META_FIELD_TIPL 0x39 #define META_FIELD_TIT1 0x3a #define META_FIELD_TKEY 0x3b #define META_FIELD_TLEN 0x3c #define META_FIELD_TMCL 0x3d #define META_FIELD_TMOO 0x3e #define META_FIELD_TOAL 0x3f #define META_FIELD_TOFN 0x40 #define META_FIELD_TOLY 0x41 #define META_FIELD_TOPE 0x42 #define META_FIELD_TOWN 0x43 #define META_FIELD_TPE2 0x44 #define META_FIELD_TPE4 0x45 #define META_FIELD_TPOS 0x46 #define META_FIELD_TPRO 0x47 #define META_FIELD_TRSN 0x48 #define META_FIELD_TRSO 0x49 #define META_FIELD_TSOA 0x4a #define META_FIELD_TSOP 0x4b #define META_FIELD_TSOT 0x4c #define META_FIELD_TSSE 0x4d #define META_FIELD_TSST 0x4e #define META_FIELD_TXXX 0x4f #define META_FIELD_WCOM 0x50 #define META_FIELD_WCOP 0x51 #define META_FIELD_WOAF 0x52 #define META_FIELD_WOAR 0x53 #define META_FIELD_WOAS 0x54 #define META_FIELD_WORS 0x55 #define META_FIELD_WPAY 0x56 #define META_FIELD_WPUB 0x57 #define META_FIELD_WXXX 0x58 /* misc. string types */ #define META_FIELD_VENDOR 0x60 #define META_FIELD_ICY_NAME 0x61 #define META_FIELD_ICY_DESCR 0x62 #define META_FIELD_ICY_GENRE 0x63 #define META_FIELD_OTHER 0xff /* integer types */ #define META_FIELD_TRACKNO 0x0100 #define META_FIELD_DISC 0x0200 #define META_FIELD_EAN_UPC 0x0300 /* float types */ #define META_FIELD_RVA2 0x010000 #define META_FIELD_RG_REFLOUDNESS 0x020000 #define META_FIELD_RG_TRACK_GAIN 0x030000 #define META_FIELD_RG_TRACK_PEAK 0x040000 #define META_FIELD_RG_ALBUM_GAIN 0x050000 #define META_FIELD_RG_ALBUM_PEAK 0x060000 /* binary types */ #define META_FIELD_APIC 0x01000000 #define META_FIELD_GEOB 0x02000000 #define META_FIELD_MODINFO 0x03000000 #define META_FIELD_HIDDEN 0x04000000 #define META_FIELD_TEXT(f) ((f)&0xff) #define META_FIELD_INT(f) ((f)&0xff00) #define META_FIELD_FLOAT(f) ((f)&0xff0000) #define META_FIELD_BIN(f) ((f)&0xff000000) /* field flags */ #define META_FIELD_UNIQUE 0x01 /* only one instance is permitted */ #define META_FIELD_MANDATORY 0x02 /* field cannot be removed */ #define META_FIELD_LOCATOR 0x80 /* field_val is only a locator to the actual content */ typedef struct _meta_frame_t { int tag; /* one of META_TAG_*, owner tag of this frame */ int type; /* one of META_FIELD_* */ int flags; char * field_name; char * field_val; /* UTF8 */ int int_val; float float_val; void * data; int length; void * source; /* source widget in File info dialog */ struct _meta_frame_t * next; } meta_frame_t; typedef struct { int writable; int valid_tags; /* tags that are valid (but may not be actually present) */ meta_frame_t * root; /* linked list */ void * fdec; /* optional; points to the owner fdec */ } metadata_t; /* type of META_FIELD_MODINFO */ #ifdef HAVE_MOD typedef struct _mod_info { char title[MAXLEN]; int active; #ifdef HAVE_MOD_INFO int type; unsigned int samples; unsigned int instruments; unsigned int patterns; unsigned int channels; #endif /* HAVE_MOD_INFO */ } mod_info; #endif /* HAVE_MOD */ /* data model functions */ char * meta_get_tagname(int tag); int meta_tag_from_name(char * name); int meta_get_fieldname(int type, char ** str); int meta_get_fieldname_embedded(int tag, int type, char ** str); char * meta_get_field_parsefmt(int type); char * meta_get_field_renderfmt(int type); int meta_frame_type_from_name(char * name); int meta_frame_type_from_embedded_name(int tag, char * name); GSList * meta_get_possible_fields(int tag); int meta_get_default_flags(int tag, int type); void metadata_add_mandatory_frames(metadata_t * meta, int tag); void metadata_clone_frame(metadata_t * meta, meta_frame_t * frame); /* object methods */ metadata_t * metadata_new(void); void metadata_free(metadata_t * meta); meta_frame_t * meta_frame_new(void); void meta_frame_free(meta_frame_t * meta_frame); void metadata_add_frame(metadata_t * meta, meta_frame_t * frame); void metadata_remove_frame(metadata_t * meta, meta_frame_t * frame); /* helper functions */ meta_frame_t * metadata_get_frame_by_type(metadata_t * meta, int type, meta_frame_t * root); meta_frame_t * metadata_get_frame_by_tag(metadata_t * meta, int tag, meta_frame_t * root); meta_frame_t * metadata_get_frame_by_tag_and_type(metadata_t * meta, int tag, int type, meta_frame_t * root); meta_frame_t * metadata_add_frame_from_keyval(metadata_t * meta, int tag, char * key, char * val); metadata_t * metadata_from_mpeg_stream_data(char * str); metadata_t * metadata_clone(metadata_t * meta, int tags); /* low-level utils */ u_int32_t meta_read_int32(unsigned char * buf); u_int64_t meta_read_int64(unsigned char * buf); void meta_write_int32(u_int32_t val, unsigned char * buf); void meta_write_int64(u_int64_t val, unsigned char * buf); /* debug functions */ /* void metadata_dump(metadata_t * meta); void meta_dump_frame(meta_frame_t * frame); */ #endif /* _METADATA_H */ aqualung-0.9beta11/src/metadata.c0000644000175000001440000007214211315737506013643 00000000000000/* -*- linux-c -*- Copyright (C) 2007 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: metadata.c 1085 2009-12-18 17:22:50Z peterszilagyi $ */ #include #include #include #include #include "common.h" #include "i18n.h" #include "utils.h" #include "options.h" #include "metadata.h" #include "metadata_api.h" extern options_t options; /* the data model */ struct { int type; char * name; /* name displayed to the user */ char * parse_fmt; /* format string for conversion from int/float types */ char * render_fmt; /* format string for conversion to int/float types */ int tags; /* tags this frame can be present in */ struct { int tag; int flags; char * name; /* name as it is written in tag */ } const emb_names[META_N_TAGS]; } const meta_model[] = { {META_FIELD_TITLE, X_("Title"), "", "", META_TAG_APE | META_TAG_OXC | META_TAG_ID3v1 | META_TAG_ID3v2 | META_TAG_MPEGSTREAM, {{META_TAG_APE, 0, "Title"}, {META_TAG_OXC, 0, "title"}, {META_TAG_ID3v1, META_FIELD_UNIQUE | META_FIELD_MANDATORY, "Title"}, {META_TAG_ID3v2, META_FIELD_UNIQUE, "TIT2"}, {META_TAG_MPEGSTREAM, 0, "Title"}}}, {META_FIELD_ARTIST, X_("Artist"), "", "", META_TAG_APE | META_TAG_OXC | META_TAG_ID3v1 | META_TAG_ID3v2 | META_TAG_MPEGSTREAM, {{META_TAG_APE, 0, "Artist"}, {META_TAG_OXC, 0, "artist"}, {META_TAG_ID3v1, META_FIELD_UNIQUE | META_FIELD_MANDATORY, "Artist"}, {META_TAG_ID3v2, META_FIELD_UNIQUE, "TPE1"}, {META_TAG_MPEGSTREAM, 0, "Artist"}}}, {META_FIELD_ALBUM, X_("Album"), "", "", META_TAG_APE | META_TAG_OXC | META_TAG_ID3v1 | META_TAG_ID3v2 | META_TAG_MPEGSTREAM, {{META_TAG_APE, 0, "Album"}, {META_TAG_OXC, 0, "album"}, {META_TAG_ID3v1, META_FIELD_UNIQUE | META_FIELD_MANDATORY, "Album"}, {META_TAG_ID3v2, META_FIELD_UNIQUE, "TALB"}, {META_TAG_MPEGSTREAM, 0, "Album"}}}, {META_FIELD_DATE, X_("Date"), "", "", META_TAG_APE | META_TAG_OXC | META_TAG_ID3v1 | META_TAG_ID3v2, {{META_TAG_APE, META_FIELD_UNIQUE, "Year"}, {META_TAG_OXC, META_FIELD_UNIQUE, "date"}, {META_TAG_ID3v1, META_FIELD_UNIQUE | META_FIELD_MANDATORY, "Year"}, {META_TAG_ID3v2, META_FIELD_UNIQUE, "TDRC"}}}, {META_FIELD_GENRE, X_("Genre"), "", "", META_TAG_APE | META_TAG_OXC | META_TAG_ID3v1 | META_TAG_ID3v2, {{META_TAG_APE, META_FIELD_UNIQUE, "Genre"}, {META_TAG_OXC, META_FIELD_UNIQUE, "genre"}, {META_TAG_ID3v1, META_FIELD_UNIQUE | META_FIELD_MANDATORY, "Genre"}, {META_TAG_ID3v2, META_FIELD_UNIQUE, "TCON"}}}, {META_FIELD_TRACKNO, X_("Track No."), "%d", "%02d", META_TAG_APE | META_TAG_OXC | META_TAG_ID3v1 | META_TAG_ID3v2, {{META_TAG_APE, META_FIELD_UNIQUE, "Track"}, {META_TAG_OXC, META_FIELD_UNIQUE, "tracknumber"}, {META_TAG_ID3v1, META_FIELD_UNIQUE, "Track"}, {META_TAG_ID3v2, META_FIELD_UNIQUE, "TRCK"}}}, {META_FIELD_COMMENT, X_("Comment"), "", "", META_TAG_APE | META_TAG_OXC | META_TAG_ID3v1 | META_TAG_ID3v2, {{META_TAG_APE, 0, "Comment"}, {META_TAG_OXC, 0, "comment"}, {META_TAG_ID3v1, META_FIELD_UNIQUE | META_FIELD_MANDATORY, "Comment"}, {META_TAG_ID3v2, META_FIELD_UNIQUE, "COMM"}}}, {META_FIELD_DISC, X_("Disc"), "%d", "%d", META_TAG_APE | META_TAG_OXC, {{META_TAG_APE, 0, "Disc"}, {META_TAG_OXC, 0, "disc"}}}, {META_FIELD_PERFORMER, X_("Performer"), "", "", META_TAG_OXC, {{META_TAG_OXC, 0, "performer"}}}, {META_FIELD_DESCRIPTION, X_("Description"), "", "", META_TAG_OXC, {{META_TAG_OXC, 0, "description"}}}, {META_FIELD_ORGANIZATION, X_("Organization"), "", "", META_TAG_OXC, {{META_TAG_OXC, 0, "organization"}}}, {META_FIELD_LOCATION, X_("Location"), "", "", META_TAG_OXC, {{META_TAG_OXC, 0, "location"}}}, {META_FIELD_CONTACT, X_("Contact"), "", "", META_TAG_OXC, {{META_TAG_OXC, 0, "contact"}}}, {META_FIELD_LICENSE, X_("License"), "", "", META_TAG_OXC, {{META_TAG_OXC, 0, "license"}}}, {META_FIELD_COPYRIGHT, X_("Copyright"), "", "", META_TAG_APE | META_TAG_OXC | META_TAG_ID3v2, {{META_TAG_APE, 0, "Copyright"}, {META_TAG_OXC, 0, "copyright"}, {META_TAG_ID3v2, META_FIELD_UNIQUE, "TCOP"}}}, {META_FIELD_ISRC, X_("ISRC"), "", "", META_TAG_APE | META_TAG_OXC | META_TAG_ID3v2, {{META_TAG_APE, 0, "ISRC"}, {META_TAG_OXC, 0, "isrc"}, {META_TAG_ID3v2, META_FIELD_UNIQUE, "TSRC"}}}, {META_FIELD_VERSION, X_("Version"), "", "", META_TAG_OXC, {{META_TAG_OXC, 0, "Version"}}}, {META_FIELD_SUBTITLE, X_("Subtitle"), "", "", META_TAG_APE | META_TAG_ID3v2, {{META_TAG_APE, 0, "Subtitle"}, {META_TAG_ID3v2, META_FIELD_UNIQUE, "TIT3"}}}, {META_FIELD_DEBUT_ALBUM, X_("Debut Album"), "", "", META_TAG_APE, {{META_TAG_APE, 0, "Debut album"}}}, {META_FIELD_PUBLISHER, X_("Publisher"), "", "", META_TAG_APE | META_TAG_ID3v2, {{META_TAG_APE, 0, "Publisher"}, {META_TAG_ID3v2, META_FIELD_UNIQUE, "TPUB"}}}, {META_FIELD_CONDUCTOR, X_("Conductor"), "", "", META_TAG_APE | META_TAG_ID3v2, {{META_TAG_APE, 0, "Conductor"}, {META_TAG_ID3v2, META_FIELD_UNIQUE, "TCON"}}}, {META_FIELD_COMPOSER, X_("Composer"), "", "", META_TAG_APE | META_TAG_ID3v2, {{META_TAG_APE, 0, "Composer"}, {META_TAG_ID3v2, META_FIELD_UNIQUE, "TCOM"}}}, {META_FIELD_PRIGHT, X_("Publication Right"), "", "", META_TAG_APE, {{META_TAG_APE, 0, "Publicationright"}}}, {META_FIELD_FILE, X_("File"), "", "", META_TAG_APE, {{META_TAG_APE, 0, "File"}}}, {META_FIELD_EAN_UPC, X_("EAN/UPC"), "%d", "%d", META_TAG_APE, {{META_TAG_APE, 0, "EAN/UPC"}}}, {META_FIELD_ISBN, X_("ISBN"), "", "", META_TAG_APE, {{META_TAG_APE, 0, "ISBN"}}}, {META_FIELD_CATALOG, X_("Catalog Number"), "", "", META_TAG_APE, {{META_TAG_APE, 0, "Catalog"}}}, {META_FIELD_LC, X_("Label Code"), "", "", META_TAG_APE, {{META_TAG_APE, 0, "LC"}}}, {META_FIELD_RECORD_DATE, X_("Record Date"), "", "", META_TAG_APE, {{META_TAG_APE, 0, "Record Date"}}}, {META_FIELD_RECORD_LOC, X_("Record Location"), "", "", META_TAG_APE, {{META_TAG_APE, 0, "Record Location"}}}, {META_FIELD_MEDIA, X_("Media"), "", "", META_TAG_APE | META_TAG_ID3v2, {{META_TAG_APE, 0, "Media"}, {META_TAG_ID3v2, META_FIELD_UNIQUE, "TMED"}}}, {META_FIELD_INDEX, X_("Index"), "", "", META_TAG_APE, {{META_TAG_APE, 0, "Index"}}}, {META_FIELD_RELATED, X_("Related"), "", "", META_TAG_APE, {{META_TAG_APE, 0, "Related"}}}, {META_FIELD_ABSTRACT, X_("Abstract"), "", "", META_TAG_APE, {{META_TAG_APE, 0, "Abstract"}}}, {META_FIELD_LANGUAGE, X_("Language"), "", "", META_TAG_APE | META_TAG_ID3v2, {{META_TAG_APE, 0, "Language"}, {META_TAG_ID3v2, META_FIELD_UNIQUE, "TLAN"}}}, {META_FIELD_BIBLIOGRAPHY, X_("Bibliography"), "", "", META_TAG_APE, {{META_TAG_APE, 0, "Bibliography"}}}, {META_FIELD_INTROPLAY, X_("Introplay"), "", "", META_TAG_APE, {{META_TAG_APE, 0, "Introplay"}}}, {META_FIELD_TBPM, X_("BPM"), "", "", META_TAG_ID3v2, {{META_TAG_ID3v2, META_FIELD_UNIQUE, "TBPM"}}}, {META_FIELD_TDEN, X_("Encoding Time"), "", "", META_TAG_ID3v2, {{META_TAG_ID3v2, META_FIELD_UNIQUE, "TDEN"}}}, {META_FIELD_TDLY, X_("Playlist Delay"), "", "", META_TAG_ID3v2, {{META_TAG_ID3v2, META_FIELD_UNIQUE, "TDLY"}}}, {META_FIELD_TDOR, X_("Original Release Time"), "", "", META_TAG_ID3v2, {{META_TAG_ID3v2, META_FIELD_UNIQUE, "TDOR"}}}, {META_FIELD_TDRL, X_("Release Time"), "", "", META_TAG_ID3v2, {{META_TAG_ID3v2, META_FIELD_UNIQUE, "TDRL"}}}, {META_FIELD_TDTG, X_("Tagging Time"), "", "", META_TAG_ID3v2, {{META_TAG_ID3v2, META_FIELD_UNIQUE, "TDTG"}}}, {META_FIELD_TENC, X_("Encoded by"), "", "", META_TAG_ID3v2, {{META_TAG_ID3v2, META_FIELD_UNIQUE, "TENC"}}}, {META_FIELD_T_E_X_T, X_("Lyricist/Text Writer"), "", "", META_TAG_ID3v2, {{META_TAG_ID3v2, META_FIELD_UNIQUE, "TEXT"}}}, {META_FIELD_TFLT, X_("File Type"), "", "", META_TAG_ID3v2, {{META_TAG_ID3v2, META_FIELD_UNIQUE, "TFLT"}}}, {META_FIELD_TIPL, X_("Involved People"), "", "", META_TAG_ID3v2, {{META_TAG_ID3v2, META_FIELD_UNIQUE, "TIPL"}}}, {META_FIELD_TIT1, X_("Content Group"), "", "", META_TAG_ID3v2, {{META_TAG_ID3v2, META_FIELD_UNIQUE, "TIT1"}}}, {META_FIELD_TKEY, X_("Initial key"), "", "", META_TAG_ID3v2, {{META_TAG_ID3v2, META_FIELD_UNIQUE, "TKEY"}}}, {META_FIELD_TLEN, X_("Length"), "", "", META_TAG_ID3v2, {{META_TAG_ID3v2, META_FIELD_UNIQUE, "TLEN"}}}, {META_FIELD_TMCL, X_("Musician Credits"), "", "", META_TAG_ID3v2, {{META_TAG_ID3v2, META_FIELD_UNIQUE, "TMCL"}}}, {META_FIELD_TMOO, X_("Mood"), "", "", META_TAG_ID3v2, {{META_TAG_ID3v2, META_FIELD_UNIQUE, "TMOO"}}}, {META_FIELD_TOAL, X_("Original Album"), "", "", META_TAG_ID3v2, {{META_TAG_ID3v2, META_FIELD_UNIQUE, "TOAL"}}}, {META_FIELD_TOFN, X_("Original Filename"), "", "", META_TAG_ID3v2, {{META_TAG_ID3v2, META_FIELD_UNIQUE, "TOFN"}}}, {META_FIELD_TOLY, X_("Original Lyricist"), "", "", META_TAG_ID3v2, {{META_TAG_ID3v2, META_FIELD_UNIQUE, "TOLY"}}}, {META_FIELD_TOPE, X_("Original Artist"), "", "", META_TAG_ID3v2, {{META_TAG_ID3v2, META_FIELD_UNIQUE, "TOPE"}}}, {META_FIELD_TOWN, X_("File Owner"), "", "", META_TAG_ID3v2, {{META_TAG_ID3v2, META_FIELD_UNIQUE, "TOWN"}}}, {META_FIELD_TPE2, X_("Band/Orchestra"), "", "", META_TAG_ID3v2, {{META_TAG_ID3v2, META_FIELD_UNIQUE, "TPE2"}}}, {META_FIELD_TPE4, X_("Interpreted/Remixed"), "", "", META_TAG_ID3v2, {{META_TAG_ID3v2, META_FIELD_UNIQUE, "TPE4"}}}, {META_FIELD_TPOS, X_("Part Of A Set"), "", "", META_TAG_ID3v2, {{META_TAG_ID3v2, META_FIELD_UNIQUE, "TPOS"}}}, {META_FIELD_TPRO, X_("Produced"), "", "", META_TAG_ID3v2, {{META_TAG_ID3v2, META_FIELD_UNIQUE, "TPRO"}}}, {META_FIELD_TRSN, X_("Internet Radio Station Name"), "", "", META_TAG_ID3v2, {{META_TAG_ID3v2, META_FIELD_UNIQUE, "TRSN"}}}, {META_FIELD_TRSO, X_("Internet Radio Station Owner"), "", "", META_TAG_ID3v2, {{META_TAG_ID3v2, META_FIELD_UNIQUE, "TRSO"}}}, {META_FIELD_TSOA, X_("Album Sort Order"), "", "", META_TAG_ID3v2, {{META_TAG_ID3v2, META_FIELD_UNIQUE, "TSOA"}}}, {META_FIELD_TSOP, X_("Performer Sort Order"), "", "", META_TAG_ID3v2, {{META_TAG_ID3v2, META_FIELD_UNIQUE, "TSOP"}}}, {META_FIELD_TSOT, X_("Title Sort Order"), "", "", META_TAG_ID3v2, {{META_TAG_ID3v2, META_FIELD_UNIQUE, "TSOT"}}}, {META_FIELD_TSSE, X_("Software"), "", "", META_TAG_ID3v2, {{META_TAG_ID3v2, META_FIELD_UNIQUE, "TSSE"}}}, {META_FIELD_TSST, X_("Set Subtitle"), "", "", META_TAG_ID3v2, {{META_TAG_ID3v2, META_FIELD_UNIQUE, "TSST"}}}, {META_FIELD_TXXX, X_("User Defined Text"), "", "", META_TAG_ID3v2, {{META_TAG_ID3v2, 0, "TXXX"}}}, {META_FIELD_WCOM, X_("Commercial Information"), "", "", META_TAG_ID3v2, {{META_TAG_ID3v2, META_FIELD_UNIQUE, "WCOM"}}}, {META_FIELD_WCOP, X_("Copyright/Legal Information"), "", "", META_TAG_ID3v2, {{META_TAG_ID3v2, META_FIELD_UNIQUE, "WCOP"}}}, {META_FIELD_WOAF, X_("Official Audio File Website"), "", "", META_TAG_ID3v2, {{META_TAG_ID3v2, META_FIELD_UNIQUE, "WOAF"}}}, {META_FIELD_WOAR, X_("Official Artist Website"), "", "", META_TAG_ID3v2, {{META_TAG_ID3v2, META_FIELD_UNIQUE, "WOAR"}}}, {META_FIELD_WOAS, X_("Official Audio Source Website"), "", "", META_TAG_ID3v2, {{META_TAG_ID3v2, META_FIELD_UNIQUE, "WOAS"}}}, {META_FIELD_WORS, X_("Official Radio Station Website"), "", "", META_TAG_ID3v2, {{META_TAG_ID3v2, META_FIELD_UNIQUE, "WORS"}}}, {META_FIELD_WPAY, X_("Payment"), "", "", META_TAG_ID3v2, {{META_TAG_ID3v2, META_FIELD_UNIQUE, "WPAY"}}}, {META_FIELD_WPUB, X_("Publisher's Official Website"), "", "", META_TAG_ID3v2, {{META_TAG_ID3v2, META_FIELD_UNIQUE, "WPUB"}}}, {META_FIELD_WXXX, X_("User Defined URL"), "", "", META_TAG_ID3v2, {{META_TAG_ID3v2, 0, "WXXX"}}}, {META_FIELD_VENDOR, X_("Vendor"), "", "", META_TAG_OXC, {{META_TAG_OXC, META_FIELD_UNIQUE | META_FIELD_MANDATORY, "vendor"}}}, {META_FIELD_RG_REFLOUDNESS, X_("ReplayGain Reference Loudness"), "%f", "%02.1f dB", META_TAG_APE | META_TAG_OXC, {{META_TAG_APE, META_FIELD_UNIQUE, "Replaygain_reference_loudness"}, {META_TAG_OXC, META_FIELD_UNIQUE, "replaygain_reference_loudness"}}}, {META_FIELD_RG_TRACK_GAIN, X_("ReplayGain Track Gain"), "%f", "%1.2f dB", META_TAG_APE | META_TAG_OXC | META_TAG_MPC_RGDATA, {{META_TAG_APE, META_FIELD_UNIQUE, "Replaygain_track_gain"}, {META_TAG_OXC, META_FIELD_UNIQUE, "replaygain_track_gain"}, {META_TAG_MPC_RGDATA, META_FIELD_UNIQUE | META_FIELD_MANDATORY, "track_gain"}}}, {META_FIELD_RG_TRACK_PEAK, X_("ReplayGain Track Peak"), "%f", "%f", META_TAG_APE | META_TAG_OXC | META_TAG_MPC_RGDATA, {{META_TAG_APE, META_FIELD_UNIQUE, "Replaygain_track_peak"}, {META_TAG_OXC, META_FIELD_UNIQUE, "replaygain_track_peak"}, {META_TAG_MPC_RGDATA, META_FIELD_UNIQUE | META_FIELD_MANDATORY, "track_peak"}}}, {META_FIELD_RG_ALBUM_GAIN, X_("ReplayGain Album Gain"), "%f dB", "%1.2f dB", META_TAG_APE | META_TAG_OXC | META_TAG_MPC_RGDATA, {{META_TAG_APE, META_FIELD_UNIQUE, "Replaygain_album_gain"}, {META_TAG_OXC, META_FIELD_UNIQUE, "replaygain_album_gain"}, {META_TAG_MPC_RGDATA, META_FIELD_UNIQUE | META_FIELD_MANDATORY, "album_gain"}}}, {META_FIELD_RG_ALBUM_PEAK, X_("ReplayGain Album Peak"), "%f", "%f", META_TAG_APE | META_TAG_OXC | META_TAG_MPC_RGDATA, {{META_TAG_APE, META_FIELD_UNIQUE, "Replaygain_album_peak"}, {META_TAG_OXC, META_FIELD_UNIQUE, "replaygain_album_peak"}, {META_TAG_MPC_RGDATA, META_FIELD_UNIQUE | META_FIELD_MANDATORY, "album_peak"}}}, {META_FIELD_ICY_NAME, X_("Icy-Name"), "", "", META_TAG_GEN_STREAM, {{META_TAG_GEN_STREAM, 0, "Icy-Name"}}}, {META_FIELD_ICY_DESCR, X_("Icy-Description"), "", "", META_TAG_GEN_STREAM, {{META_TAG_GEN_STREAM, 0, "Icy-Description"}}}, {META_FIELD_ICY_GENRE, X_("Icy-Genre"), "", "", META_TAG_GEN_STREAM, {{META_TAG_GEN_STREAM, 0, "Icy-Genre"}}}, {META_FIELD_RVA2, X_("RVA"), "%f dB", "%2.2f dB", META_TAG_ID3v2, {{META_TAG_ID3v2, META_FIELD_UNIQUE, "RVA2"}}}, {META_FIELD_APIC, X_("Attached Picture"), "", "", META_TAG_ID3v2 | META_TAG_APE | META_TAG_FLAC_APIC, {{META_TAG_ID3v2, 0, "APIC"}, {META_TAG_APE, 0, "Cover Art"}, {META_TAG_FLAC_APIC, 0, "APIC"}}}, {META_FIELD_GEOB, X_("Binary Object"), "", "", 0, {}}, {-1}}; /* data model functions */ char * meta_get_tagname(int tag) { switch (tag) { case META_TAG_NULL: return _("NULL"); case META_TAG_ID3v1: return _("ID3v1"); case META_TAG_ID3v2: return _("ID3v2"); case META_TAG_APE: return _("APE"); case META_TAG_OXC: return _("Ogg Xiph Comments"); case META_TAG_FLAC_APIC: return _("FLAC Pictures"); case META_TAG_MPC_RGDATA: return _("Musepack ReplayGain"); case META_TAG_GEN_STREAM: return _("Generic StreamMeta"); case META_TAG_MPEGSTREAM: return _("MPEG StreamMeta"); case META_TAG_MODINFO: return _("Module info"); default: return _("Unknown"); } } int meta_tag_from_name(char * name) { int i = 1; if (strcmp(name, meta_get_tagname(0)) == 0) return 0; while (1) { if (strcmp(name, meta_get_tagname(i)) == 0) { return i; } i <<= 1; } fprintf(stderr, "meta_tag_from_name: programmer error\n"); return -1; } int meta_get_fieldname(int type, char ** str) { int i; for (i = 0; meta_model[i].type != -1; i++) { if (type == meta_model[i].type) { *str = _(meta_model[i].name); return 1; } } return 0; } int meta_get_fieldname_embedded(int tag, int type, char ** str) { int i; for (i = 0; meta_model[i].type != -1; i++) { if (type == meta_model[i].type) { int j; for (j = 0; j < META_N_TAGS; j++) { if (tag == meta_model[i].emb_names[j].tag) { *str = meta_model[i].emb_names[j].name; return 1; } } return 0; } } return 0; } char * meta_get_field_parsefmt(int type) { int i; for (i = 0; meta_model[i].type != -1; i++) { if (type == meta_model[i].type) { return meta_model[i].parse_fmt; } } if (META_FIELD_INT(type)) { return "%d"; } if (META_FIELD_FLOAT(type)) { return "%f"; } return ""; } char * meta_get_field_renderfmt(int type) { int i; for (i = 0; meta_model[i].type != -1; i++) { if (type == meta_model[i].type) { return meta_model[i].render_fmt; } } if (META_FIELD_INT(type)) { return "%d"; } if (META_FIELD_FLOAT(type)) { return "%f"; } return ""; } int meta_frame_type_from_name(char * name) { int i; for (i = 0; meta_model[i].type != -1; i++) { if (strcmp(name, _(meta_model[i].name)) == 0) { return meta_model[i].type; } } return META_FIELD_OTHER; } int meta_frame_type_from_embedded_name(int tag, char * name) { int i; for (i = 0; meta_model[i].type != -1; i++) { int j; for (j = 0; j < META_N_TAGS; j++) { if ((tag == meta_model[i].emb_names[j].tag) && (strcasecmp(name, meta_model[i].emb_names[j].name) == 0)) { return meta_model[i].type; } } } return META_FIELD_OTHER; } GSList * meta_get_possible_fields(int tag) { GSList * list = NULL; int i; for (i = 0; meta_model[i].type != -1; i++) { if ((tag & meta_model[i].tags) != 0) { list = g_slist_append(list, GINT_TO_POINTER(meta_model[i].type)); } } return list; } int meta_get_default_flags(int tag, int type) { int i; for (i = 0; meta_model[i].type != -1; i++) { if (type == meta_model[i].type) { int j; for (j = 0; j < META_N_TAGS; j++) { if (tag == meta_model[i].emb_names[j].tag) { return meta_model[i].emb_names[j].flags; } } return 0; } } return 0; } meta_frame_t * metadata_find_companion_frame(metadata_t * meta, meta_frame_t * frame) { meta_frame_t * f; int tag = META_TAG_MAX; while (tag > 0) { if (tag != frame->tag) { f = metadata_get_frame_by_tag_and_type(meta, tag, frame->type, NULL); if (f) { return f; } } tag >>= 1; } return NULL; } /* search for frames other than the given frame itself that are of the same type and copy their contents */ void metadata_clone_frame(metadata_t * meta, meta_frame_t * frame) { meta_frame_t * companion = metadata_find_companion_frame(meta, frame); if (companion == NULL) { return; } if (companion->field_name != NULL) { if (frame->field_name != NULL) { free(frame->field_name); } frame->field_name = strdup(companion->field_name); } if (companion->field_val != NULL) { frame->field_val = strdup(companion->field_val); } frame->int_val = companion->int_val; frame->float_val = companion->float_val; if (companion->length > 0) { frame->length = companion->length; frame->data = (unsigned char *)malloc(frame->length); if (frame->data == NULL) { fprintf(stderr, "metadata_clone_frame: malloc error\n"); return; } memcpy(frame->data, companion->data, frame->length); } } void metadata_add_mandatory_frames(metadata_t * meta, int tag) { int i; for (i = 0; meta_model[i].type != -1; i++) { int j; for (j = 0; j < META_N_TAGS; j++) { if ((tag == meta_model[i].emb_names[j].tag) && ((meta_model[i].emb_names[j].flags & META_FIELD_MANDATORY) != 0)) { meta_frame_t * frame = meta_frame_new(); char * str; frame->tag = tag; frame->type = meta_model[i].type; frame->flags = meta_get_default_flags(tag, frame->type); if (meta_get_fieldname(frame->type, &str)) { if (options.metaedit_auto_clone) { metadata_clone_frame(meta, frame); } if (frame->field_name == NULL) { frame->field_name = strdup(str); } } else { fprintf(stderr, "metadata_add_mandatory_frames: programmer error\n"); meta_frame_free(frame); return; } if (frame->field_val == NULL) { frame->field_val = strdup(""); } metadata_add_frame(meta, frame); } } } } /* object methods */ metadata_t * metadata_new(void) { metadata_t * meta = NULL; if ((meta = calloc(1, sizeof(metadata_t))) == NULL) { fprintf(stderr, "metadata.c: metadata_new() failed: calloc error\n"); return NULL; } return meta; } void metadata_free(metadata_t * meta) { meta_frame_t * p; meta_frame_t * q; if (meta->root == NULL) { free(meta); return; } p = meta->root; while (p != NULL) { q = p->next; meta_frame_free(p); p = q; } free(meta); } meta_frame_t * meta_frame_new(void) { meta_frame_t * meta_frame = NULL; if ((meta_frame = calloc(1, sizeof(meta_frame_t))) == NULL) { fprintf(stderr, "metadata.c: meta_frame_new() failed: calloc error\n"); return NULL; } return meta_frame; } void meta_frame_free(meta_frame_t * meta_frame) { if (meta_frame->field_name != NULL) free(meta_frame->field_name); if (meta_frame->field_val != NULL) free(meta_frame->field_val); if (meta_frame->data != NULL) free(meta_frame->data); free(meta_frame); } void metadata_add_frame(metadata_t * meta, meta_frame_t * frame) { frame->next = NULL; if (meta->root == NULL) { meta->root = frame; } else { meta_frame_t * prev = meta->root; while (prev->next != NULL) { prev = prev->next; } prev->next = frame; } } /* take frame out of meta; does not free frame! */ void metadata_remove_frame(metadata_t * meta, meta_frame_t * frame) { meta_frame_t * prev; if (meta->root == frame) { meta->root = frame->next; return; } prev = meta->root; while (prev->next != frame) { prev = prev->next; } prev->next = frame->next; } /* helper functions */ /* Search for frame of given type. Passing NULL as root will search from * the beginning of the frame list. Passing the previous return value of * this function as root allows getting multiple frames of the same type. * Returns NULL if there are no (more) frames of the specified type. */ meta_frame_t * metadata_get_frame_by_type(metadata_t * meta, int type, meta_frame_t * root) { meta_frame_t * frame; if (meta == NULL) { return NULL; } if (root == NULL) { frame = meta->root; } else { frame = root->next; } if (frame == NULL) { return NULL; } while (frame->type != type) { frame = frame->next; if (frame == NULL) { return NULL; } } return frame; } /* Search for frame belonging to tag. Passing NULL as root will search from * the beginning of the frame list. Passing the previous return value of * this function as root allows getting multiple frames of the same tag. * Returns NULL if there are no (more) frames of the specified tag. */ meta_frame_t * metadata_get_frame_by_tag(metadata_t * meta, int tag, meta_frame_t * root) { meta_frame_t * frame; if (root == NULL) { frame = meta->root; } else { frame = root->next; } if (frame == NULL) { return NULL; } while (frame->tag != tag) { frame = frame->next; if (frame == NULL) { return NULL; } } return frame; } /* Search for frame of given type, belonging to tag. Passing NULL as * root will search from the beginning of the frame list. Passing the * previous return value of this function as root allows getting * multiple frames of the same tag. Returns NULL if there are no * (more) frames of the specified tag. */ meta_frame_t * metadata_get_frame_by_tag_and_type(metadata_t * meta, int tag, int type, meta_frame_t * root) { meta_frame_t * frame; if (meta == NULL) { return NULL; } if (root == NULL) { frame = meta->root; } else { frame = root->next; } if (frame == NULL) { return NULL; } while (frame->tag != tag || frame->type != type) { frame = frame->next; if (frame == NULL) { return NULL; } } return frame; } meta_frame_t * metadata_add_frame_from_keyval(metadata_t * meta, int tag, char * key, char * val) { meta_frame_t * frame = meta_frame_new(); char * str; char * parsefmt; frame->tag = tag; frame->type = meta_frame_type_from_embedded_name(tag, key); if (meta_get_fieldname(frame->type, &str)) { frame->field_name = strdup(str); } else { frame->field_name = strdup(key); } frame->field_val = strdup(val); frame->flags = meta_get_default_flags(tag, frame->type); parsefmt = meta_get_field_parsefmt(frame->type); if (META_FIELD_INT(frame->type)) { if (sscanf(val, parsefmt, &frame->int_val) < 1) { fprintf(stderr, "warning: couldn't parse integer value from '%s' using format string '%s'\n", val, parsefmt); } } else if (META_FIELD_FLOAT(frame->type)) { if (sscanf(val, parsefmt, &frame->float_val) < 1) { fprintf(stderr, "warning: couldn't parse float value from '%s' using format string '%s'\n", val, parsefmt); } } metadata_add_frame(meta, frame); return frame; } metadata_t * metadata_from_mpeg_stream_data(char * str) { metadata_t * meta = metadata_new(); char * s; meta->writable = 0; s = strtok(str, ";"); while (s) { char key[MAXLEN]; char val[MAXLEN]; char c; int k, n = 0; for (k = 0; ((c = s[n]) != '\0') && (c != '=') && (k < MAXLEN-1); k++) { key[k] = c; ++n; } key[k] = '\0'; ++n; if (strstr(key, "Stream") == key) { memmove(key, key+6, sizeof(key)-6); } if (str[n] == '\'') { ++n; } for (k = 0; ((c = s[n]) != '\0') && (c != '\'') && (k < MAXLEN-1); k++) { val[k] = c; ++n; } val[k] = '\0'; metadata_add_frame_from_keyval(meta, META_TAG_MPEGSTREAM, key, val); s = strtok(NULL, ";"); } return meta; } metadata_t * metadata_clone(metadata_t * meta, int tags) { metadata_t * out = metadata_new(); int tag = META_TAG_MAX; if (meta == NULL) { return NULL; } if (out == NULL) { return NULL; } /* iterate on possible output tags */ while (tag) { int i; if ((tags & tag) == 0) { tag >>= 1; continue; } /* iterate on frame types supported by this tag */ for (i = 0; meta_model[i].type != -1; i++) { meta_frame_t * frame; int type = meta_model[i].type; if ((tag & meta_model[i].tags) == 0) { continue; } if (type == META_FIELD_VENDOR) { continue; } /* for each frame type, iterate on tags that might have it in the input meta in pref. order and copy all of them */ frame = metadata_pref_frame_by_type(meta, type, NULL); while (frame != NULL) { meta_frame_t * fout = meta_frame_new(); fout->tag = tag; fout->type = type; if (frame->field_name) { fout->field_name = strdup(frame->field_name); } if (frame->field_val) { fout->field_val = strdup(frame->field_val); } fout->int_val = frame->int_val; fout->float_val = frame->float_val; fout->length = frame->length; if (fout->length > 0) { fout->data = malloc(fout->length); if (fout->data == NULL) { fprintf(stderr, "metadata_clone: malloc error\n"); return NULL; } memcpy(fout->data, frame->data, fout->length); } metadata_add_frame(out, fout); frame = metadata_pref_frame_by_type(meta, type, frame); } } tag >>= 1; } return out; } /* low-level utils */ u_int32_t meta_read_int32(unsigned char * buf) { return ((((u_int32_t)buf[0])) | (((u_int32_t)buf[1]) << 8) | (((u_int32_t)buf[2]) << 16) | (((u_int32_t)buf[3]) << 24)); } u_int64_t meta_read_int64(unsigned char * buf) { return ((((u_int64_t)buf[0])) | (((u_int64_t)buf[1]) << 8) | (((u_int64_t)buf[2]) << 16) | (((u_int64_t)buf[3]) << 24) | (((u_int64_t)buf[4]) << 32) | (((u_int64_t)buf[5]) << 40) | (((u_int64_t)buf[6]) << 48) | (((u_int64_t)buf[7]) << 56)); } void meta_write_int32(u_int32_t val, unsigned char * buf) { buf[0] = ((val & 0xff)); buf[1] = ((val >> 8) & 0xff); buf[2] = ((val >> 16) & 0xff); buf[3] = ((val >> 24) & 0xff); } void meta_write_int64(u_int64_t val, unsigned char * buf) { buf[0] = ((val & 0xff)); buf[1] = ((val >> 8) & 0xff); buf[2] = ((val >> 16) & 0xff); buf[3] = ((val >> 24) & 0xff); buf[4] = ((val >> 32) & 0xff); buf[5] = ((val >> 40) & 0xff); buf[6] = ((val >> 48) & 0xff); buf[7] = ((val >> 56) & 0xff); } /* debug functions */ /* void metadata_dump(metadata_t * meta) { meta_frame_t * frame = meta->root; printf("\nMetadata block dump, writable = %d, valid_tags = %d\n", meta->writable, meta->valid_tags); while (frame) { meta_dump_frame(frame); frame = frame->next; } } void meta_dump_frame(meta_frame_t * frame) { printf(" Tag %2d Type %4d F=0x%04x '%s' '%s' ", frame->tag, frame->type, frame->flags, frame->field_name, frame->field_val); printf("int %d float %f ptr %p len %d\n", frame->int_val, frame->float_val, frame->data, frame->length); } */ aqualung-0.9beta11/src/metadata_api.h0000644000175000001440000000671111136163537014476 00000000000000/* -*- linux-c -*- Copyright (C) 2007 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: metadata_api.h 1055 2009-01-19 20:11:53Z quasireality $ */ /* Aqualung metadata internal API usage: * - open a file_decoder on file; * - fdec->meta is the metablock of the file; * - access/change it with functions in this module; * - call fdec->meta_write to write it back to the file * (only possible if fdec->meta->writable is true); * - close the file_decoder. */ #ifndef _METADATA_API_H #define _METADATA_API_H #include #include "metadata.h" /* Query frames of a given type, with respect to preference order between tags. */ meta_frame_t * metadata_pref_frame_by_type(metadata_t * meta, int type, meta_frame_t * root); int metadata_get_string_field(metadata_t * meta, int type, char ** str); /* High-level accessor functions * * Return value: 1 if found, 0 if not found. * Note that in case of text strings, if a match is returned, * it is still owned by the meta object (only the pointer is * passed back), so it should not be freed by the caller. * Number data will be copied to the supplied pointer. */ int metadata_get_title(metadata_t * meta, char ** str); int metadata_get_artist(metadata_t * meta, char ** str); int metadata_get_album(metadata_t * meta, char ** str); int metadata_get_date(metadata_t * meta, char ** str); int metadata_get_genre(metadata_t * meta, char ** str); int metadata_get_comment(metadata_t * meta, char ** str); int metadata_get_icy_name(metadata_t * meta, char ** str); int metadata_get_icy_descr(metadata_t * meta, char ** str); int metadata_get_tracknum(metadata_t * meta, int * val); int metadata_get_rva(metadata_t * meta, float * fval); /* Return values of meta_update_basic() */ #define META_ERROR_NONE 0 #define META_ERROR_NOMEM -1 #define META_ERROR_OPEN -2 #define META_ERROR_NO_METASUPPORT -3 #define META_ERROR_NOT_WRITABLE -4 #define META_ERROR_INVALID_TRACKNO -5 #define META_ERROR_INVALID_GENRE -6 #define META_ERROR_INVALID_CODING -7 #define META_ERROR_INTERNAL -8 /* Update basic metadata fields of a file. Used for mass-tagging. * * Any input string may be NULL, in which case that field won't * be updated. Set trackno to -1 to leave it unaffected. * Existing metadata not updated will be retained. * * filename should be locale encoded, text fields should be UTF8. * * Return 0 if OK, < 0 else. * Use metadata_strerror() to get an error string from the * return value. */ int meta_update_basic(char * filename, char * title, char * artist, char * album, char * comment, char * genre, char * date, int trackno); const char * metadata_strerror(int error); #endif /* _METADATA_API_H */ aqualung-0.9beta11/src/metadata_api.c0000644000175000001440000002135311141105005014446 00000000000000/* -*- linux-c -*- Copyright (C) 2007 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: metadata_api.c 1059 2009-01-29 20:18:17Z quasireality $ */ #include #include #include #include #include "common.h" #include "i18n.h" #include "options.h" #include "decoder/file_decoder.h" #include "utils.h" #include "metadata.h" #include "metadata_api.h" #include "volume.h" extern options_t options; /* get frame of given type, with preference between different tags. preference order: MPEGSTREAM > GEN_STREAM > OXC > APE > ID3v2 > ID3v1 */ meta_frame_t * metadata_pref_frame_by_type(metadata_t * meta, int type, meta_frame_t * root) { meta_frame_t * frame; static int tag; if (root == NULL) { tag = META_TAG_MAX; } while (tag > 0) { frame = metadata_get_frame_by_tag_and_type(meta, tag, type, root); if (frame) { return frame; } tag >>= 1; } return NULL; } int metadata_get_string_field(metadata_t * meta, int type, char ** str) { meta_frame_t * frame; if (meta == NULL) return 0; frame = metadata_pref_frame_by_type(meta, type, NULL); if (frame != NULL) { *str = frame->field_val; return 1; } else { return 0; } } int metadata_get_title(metadata_t * meta, char ** str) { #ifdef HAVE_MOD meta_frame_t * frame; #endif /* HAVE_MOD */ if (meta == NULL) return 0; #ifdef HAVE_MOD frame = metadata_get_frame_by_tag_and_type(meta, META_TAG_MODINFO, META_FIELD_MODINFO, NULL); if (frame != NULL) { mod_info * mi = (mod_info *)frame->data; *str = mi->title; return 1; } #endif /* HAVE_MOD */ return metadata_get_string_field(meta, META_FIELD_TITLE, str); } int metadata_get_artist(metadata_t * meta, char ** str) { return metadata_get_string_field(meta, META_FIELD_ARTIST, str); } int metadata_get_album(metadata_t * meta, char ** str) { return metadata_get_string_field(meta, META_FIELD_ALBUM, str); } int metadata_get_date(metadata_t * meta, char ** str) { return metadata_get_string_field(meta, META_FIELD_DATE, str); } int metadata_get_genre(metadata_t * meta, char ** str) { return metadata_get_string_field(meta, META_FIELD_GENRE, str); } int metadata_get_comment(metadata_t * meta, char ** str) { return metadata_get_string_field(meta, META_FIELD_COMMENT, str); } int metadata_get_icy_name(metadata_t * meta, char ** str) { return metadata_get_string_field(meta, META_FIELD_ICY_NAME, str); } int metadata_get_icy_descr(metadata_t * meta, char ** str) { return metadata_get_string_field(meta, META_FIELD_ICY_DESCR, str); } int metadata_get_tracknum(metadata_t * meta, int * val) { meta_frame_t * frame; if (meta == NULL) return 0; frame = metadata_pref_frame_by_type(meta, META_FIELD_TRACKNO, NULL); if (frame != NULL) { *val = frame->int_val; return 1; } else { return 0; } } int metadata_get_rva(metadata_t * meta, float * fval) { int rva_type; meta_frame_t * frame; if (meta == NULL) return 0; switch (options.replaygain_tag_to_use) { case 0: rva_type = META_FIELD_RG_TRACK_GAIN; break; default: rva_type = META_FIELD_RG_ALBUM_GAIN; break; } frame = metadata_pref_frame_by_type(meta, rva_type, NULL); if (frame != NULL) { *fval = rva_from_replaygain(frame->float_val); return 1; } else { /* fallback on the other ReplayGain frame */ if (rva_type == META_FIELD_RG_TRACK_GAIN) { rva_type = META_FIELD_RG_ALBUM_GAIN; } else { rva_type = META_FIELD_RG_TRACK_GAIN; } frame = metadata_pref_frame_by_type(meta, rva_type, NULL); if (frame != NULL) { *fval = rva_from_replaygain(frame->float_val); return 1; } else { /* fallback on RVA frame */ frame = metadata_pref_frame_by_type(meta, META_FIELD_RVA2, NULL); if (frame != NULL) { *fval = frame->float_val; return 1; } } } return 0; } void meta_update_frame_data(meta_frame_t * frame, char * str, int val, float fval) { if (META_FIELD_TEXT(frame->type)) { if (frame->field_val != NULL) { free(frame->field_val); } frame->field_val = strdup(str); } else if (META_FIELD_INT(frame->type)) { frame->int_val = val; } else if (META_FIELD_FLOAT(frame->type)) { frame->float_val = fval; } else { /* no binary frames in update_basic mode */ fprintf(stderr, "meta_update_frame_data: programmer error\n"); } } void meta_update_frame(metadata_t * meta, int add_tags, int type, char * str, int val, float fval) { int tag = 1; while (tag) { meta_frame_t * frame; if ((meta->valid_tags & tag) == 0) { tag <<= 1; continue; } frame = metadata_get_frame_by_tag_and_type(meta, tag, type, NULL); if ((frame == NULL) && ((add_tags & tag) != 0)) { char * s; /* make sure frame type is available in this tag */ if (!meta_get_fieldname_embedded(tag, type, &s)) { tag <<= 1; continue; } /* add new frame */ frame = meta_frame_new(); if (frame == NULL) { fprintf(stderr, "meta_update_frame: calloc error\n"); return; } frame->tag = tag; frame->type = type; frame->flags = meta_get_default_flags(tag, type); meta_update_frame_data(frame, str, val, fval); metadata_add_frame(meta, frame); } else if (frame != NULL) { meta_update_frame_data(frame, str, val, fval); } tag <<= 1; } } int meta_update_basic(char * filename, char * title, char * artist, char * album, char * comment, char * genre, char * date, int trackno) { file_decoder_t * fdec = file_decoder_new(); int add_tags; int ret; if (fdec == NULL) { return META_ERROR_NOMEM; } if (file_decoder_open(fdec, filename) != 0) { file_decoder_delete(fdec); return META_ERROR_OPEN; } if (fdec->meta == NULL) { file_decoder_close(fdec); file_decoder_delete(fdec); return META_ERROR_NO_METASUPPORT; } if (!fdec->meta->writable) { file_decoder_close(fdec); file_decoder_delete(fdec); return META_ERROR_NOT_WRITABLE; } if (fdec->file_lib == MAD_LIB) { add_tags = 0; if (options.batch_mpeg_add_id3v1) { add_tags |= META_TAG_ID3v1; } if (options.batch_mpeg_add_id3v2) { add_tags |= META_TAG_ID3v2; } if (options.batch_mpeg_add_ape) { add_tags |= META_TAG_APE; } } else { add_tags = fdec->meta->valid_tags; } if (fdec->meta_write == NULL) { file_decoder_close(fdec); file_decoder_delete(fdec); return META_ERROR_INTERNAL; } if (title != NULL && !is_all_wspace(title)) { cut_trailing_whitespace(title); meta_update_frame(fdec->meta, add_tags, META_FIELD_TITLE, title, 0, 0.0f); } if (artist != NULL && !is_all_wspace(artist)) { cut_trailing_whitespace(artist); meta_update_frame(fdec->meta, add_tags, META_FIELD_ARTIST, artist, 0, 0.0f); } if (album != NULL && !is_all_wspace(album)) { cut_trailing_whitespace(album); meta_update_frame(fdec->meta, add_tags, META_FIELD_ALBUM, album, 0, 0.0f); } if (trackno != -1) { meta_update_frame(fdec->meta, add_tags, META_FIELD_TRACKNO, NULL, trackno, 0.0f); } if (date != NULL && !is_all_wspace(date)) { cut_trailing_whitespace(date); meta_update_frame(fdec->meta, add_tags, META_FIELD_DATE, date, 0, 0.0f); } if (genre != NULL && !is_all_wspace(genre)) { cut_trailing_whitespace(genre); meta_update_frame(fdec->meta, add_tags, META_FIELD_GENRE, genre, 0, 0.0f); } if (comment != NULL && !is_all_wspace(comment)) { cut_trailing_whitespace(comment); meta_update_frame(fdec->meta, add_tags, META_FIELD_COMMENT, comment, 0, 0.0f); } ret = fdec->meta_write(fdec, fdec->meta); file_decoder_close(fdec); file_decoder_delete(fdec); return ret; } const char * metadata_strerror(int error) { switch (error) { case META_ERROR_NONE: return _("Success"); case META_ERROR_NOMEM: return _("Memory allocation error"); case META_ERROR_OPEN: return _("Unable to open file"); case META_ERROR_NO_METASUPPORT: return _("No metadata support for this format"); case META_ERROR_NOT_WRITABLE: return _("File is not writable"); case META_ERROR_INVALID_TRACKNO: return _("Invalid 'Track no.' field value"); case META_ERROR_INVALID_GENRE: return _("Invalid 'Genre' field value"); case META_ERROR_INVALID_CODING: return _("Conversion to target charset failed"); case META_ERROR_INTERNAL: return _("Internal error"); default: return _("Unknown error"); } } aqualung-0.9beta11/src/metadata_ape.h0000644000175000001440000000475510715406206014473 00000000000000/* -*- linux-c -*- Copyright (C) 2007 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: metadata_ape.h 884 2007-11-10 19:54:45Z tszilagyi $ */ #ifndef _METADATA_APE_H #define _METADATA_APE_H #include #include #include "common.h" #include "decoder/file_decoder.h" #include "metadata.h" #define APE_FLAG_READONLY 1 #define APE_FLAG_TEXT 0x00 #define APE_FLAG_BINARY 0x02 #define APE_FLAG_LOCATOR 0x04 #define APE_FLAG_IS_TEXT(x) (((x)&0x06)==APE_FLAG_TEXT) #define APE_FLAG_IS_BINARY(x) (((x)&0x06)==APE_FLAG_BINARY) #define APE_FLAG_IS_LOCATOR(x) (((x)&0x06)==APE_FLAG_LOCATOR) #define APE_FLAG_HEADER (1<<29) #define APE_FLAG_HAS_NO_FOOTER (1<<30) #define APE_FLAG_HAS_HEADER (1<<31) #define APE_MINIMUM_TAG_SIZE 32 #define APE_ITEM_MINIMUM_SIZE 11 #define APE_PREAMBLE "APETAGEX" typedef struct { u_int32_t flags; unsigned char key[256]; u_int32_t value_size; unsigned char * value; } ape_item_t; typedef struct { u_int32_t version; u_int32_t tag_size; u_int32_t item_count; u_int32_t flags; } ape_header_t; typedef struct { ape_header_t header; ape_header_t footer; GSList * items; /* items of type: ape_item_t */ } ape_tag_t; int meta_ape_parse(char * filename, ape_tag_t * tag); void meta_ape_free(ape_tag_t * tag); void metadata_from_ape_tag(metadata_t * meta, ape_tag_t * tag); void metadata_to_ape_tag(metadata_t * meta, ape_tag_t * tag); void meta_ape_render(ape_tag_t * tag, unsigned char * data); int meta_ape_delete(char * filename); int meta_ape_replace_or_append(char * filename, ape_tag_t * tag); /* for direct use by decoders */ int meta_ape_write_metadata(file_decoder_t * fdec, metadata_t * meta); void meta_ape_send_metadata(metadata_t * meta, file_decoder_t * fdec); #endif /* _METADATA_APE_H */ aqualung-0.9beta11/src/metadata_ape.c0000644000175000001440000004777610742221371014476 00000000000000/* -*- linux-c -*- Copyright (C) 2007 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: metadata_ape.c 979 2008-01-08 08:49:33Z tszilagyi $ */ #include #include #include #include #include #include #include #include "utils.h" #include "options.h" #include "metadata_id3v2.h" #include "metadata_ape.h" void meta_ape_free(ape_tag_t * tag) { GSList * list = tag->items; while (list != NULL) { ape_item_t * item = list->data; if (item->value != NULL) { free(item->value); } free(item); list = g_slist_next(list); } g_slist_free(tag->items); } ape_item_t * meta_ape_item_new(void) { ape_item_t * item = NULL; if ((item = calloc(1, sizeof(ape_item_t))) == NULL) { fprintf(stderr, "metadata_ape.c: meta_ape_item_new() failed: calloc error\n"); return NULL; } return item; } int meta_ape_parse(char * filename, ape_tag_t * tag) { FILE * file; ape_item_t * item = NULL; unsigned char buf[32]; unsigned char * data = NULL; long offset = 0L; int i; long file_size = 0L; long id3_length = 0L; long tag_data_size = 0L; long last_possible_offset = 0L; int ret = 0; unsigned char * value_start = NULL; unsigned char * key_start = NULL; int key_length = 0; if ((file = fopen(filename, "rb")) == NULL) { fprintf(stderr, "meta_ape_parse: fopen() failed\n"); return 0; } /* Get file size */ if (fseek(file, 0, SEEK_END) == -1) { fprintf(stderr, "meta_ape_parse: fseek() failed\n"); goto meta_ape_parse_error; } if ((file_size = ftell(file)) == -1) { fprintf(stderr, "meta_ape_parse: ftell() failed\n"); goto meta_ape_parse_error; } /* No ape or id3 tag possible in this size */ if (file_size < APE_MINIMUM_TAG_SIZE) { goto meta_ape_parse_error; } if (file_size >= 128) { /* Check for id3 tag */ if ((fseek(file, -128, SEEK_END)) != 0) { fprintf(stderr, "meta_ape_parse: fseek() failed\n"); goto meta_ape_parse_error; } if (fread(buf, 1, 3, file) < 3) { fprintf(stderr, "meta_ape_parse: fread() of id3 failed\n"); goto meta_ape_parse_error; } if (buf[0] == 'T' && buf[1] == 'A' && buf[2] == 'G' ) { id3_length = 128L; } } /* Recheck possibility for ape tag now that id3 presence is known */ if (file_size < APE_MINIMUM_TAG_SIZE + id3_length) { goto meta_ape_parse_error; } /* Check for existence of ape tag footer */ if (fseek(file, -32-id3_length, SEEK_END) != 0) { fprintf(stderr, "meta_ape_parse: fseek() failed\n"); goto meta_ape_parse_error; } if (fread(buf, 1, 32, file) < 32) { fprintf(stderr, "meta_ape_parse: fread() of tag footer failed\n"); goto meta_ape_parse_error; } if (memcmp(APE_PREAMBLE, buf, 8)) { goto meta_ape_parse_error; } tag->footer.version = meta_read_int32(buf+8); tag->footer.tag_size = meta_read_int32(buf+12); tag->footer.item_count = meta_read_int32(buf+16); tag->footer.flags = meta_read_int32(buf+20); tag_data_size = tag->footer.tag_size - 32; /* Check tag footer for validity */ if (tag->footer.tag_size < APE_MINIMUM_TAG_SIZE) { fprintf(stderr, "meta_ape_parse: corrupt tag (too short)\n"); goto meta_ape_parse_error; } if (tag->footer.tag_size + id3_length > file_size) { fprintf(stderr, "meta_ape_parse: corrupt tag (too large)\n"); goto meta_ape_parse_error; } if (tag->footer.item_count > tag_data_size / APE_ITEM_MINIMUM_SIZE) { fprintf(stderr, "meta_ape_parse: corrupt tag (item count too large)\n"); goto meta_ape_parse_error; } if ((data = (unsigned char *)malloc(tag_data_size)) == NULL) { fprintf(stderr, "meta_ape_parse: malloc() failed\n"); goto meta_ape_parse_error; } if (fseek(file, -(tag->footer.tag_size + id3_length), SEEK_END) != 0) { fprintf(stderr, "meta_ape_parse: fseek() failed\n"); goto meta_ape_parse_error; } if (fread(data, 1, tag_data_size, file) < tag_data_size) { fprintf(stderr, "meta_ape_parse: fread() of tag data failed\n"); goto meta_ape_parse_error; } last_possible_offset = tag_data_size - APE_ITEM_MINIMUM_SIZE; for (i = 0; i < tag->footer.item_count; i++) { if (offset > last_possible_offset) { fprintf(stderr, "meta_ape_parse: error: last_possible_offset passed\n"); goto meta_ape_parse_error; } if ((item = meta_ape_item_new()) == NULL) { fprintf(stderr, "meta_ape_parse: malloc() failed\n"); goto meta_ape_parse_error; } item->value_size = meta_read_int32(data+offset); item->flags = meta_read_int32(data+offset+4); key_start = data + offset + 8; /* Find and check start of value */ if (item->value_size + offset + APE_ITEM_MINIMUM_SIZE > tag_data_size) { fprintf(stderr, "meta_ape_parse: corrupt tag (bad item length)\n"); goto meta_ape_parse_error; } for (value_start=key_start; value_start < key_start+256 && *value_start != '\0'; value_start++) { /* Left Blank */ } if (*value_start != '\0') { fprintf(stderr, "meta_ape_parse: corrupt tag (key length too large)\n"); goto meta_ape_parse_error; } value_start++; key_length = value_start - key_start; offset += 8 + key_length + item->value_size; if (offset < 0 || offset > tag_data_size) { fprintf(stderr, "meta_ape_parse: corrupt tag (item length too large)\n"); goto meta_ape_parse_error; } /* Copy key and value from tag data to item */ if ((item->value = (unsigned char *)malloc(item->value_size + 1)) == NULL) { fprintf(stderr, "meta_ape_parse: malloc() failed\n"); goto meta_ape_parse_error; } memcpy(item->key, key_start, key_length); memcpy(item->value, value_start, item->value_size); item->value[item->value_size] = '\0'; tag->items = g_slist_append(tag->items, (gpointer)item); } if (offset != tag_data_size) { fprintf(stderr, "meta_ape_parse: corrupt tag (data remaining)\n"); goto meta_ape_parse_error; } ret = 1; meta_ape_parse_error: if (ret == 0) { meta_ape_free(tag); } fclose(file); free(data); return ret; } int meta_ape_pictype_from_string(unsigned char * str) { char * key; int i = 0; if (strstr((char *)str, "Cover Art (") == (char *)str) { key = (char *)str+11; } else { key = (char *)str; } key[strlen(key)-1] = '\0'; while (1) { char * pic_type = meta_id3v2_apic_type_to_string(i); if (pic_type == NULL) { return 0; } if (strcasestr(pic_type, key) == pic_type) { return i; } ++i; } return 0; /* type: other */ } void meta_ape_add_pic_frame(metadata_t * meta, ape_item_t * item) { meta_frame_t * frame; GdkPixbufLoader * loader; GdkPixbufFormat * format; gchar ** mime_types; int len1 = strlen((char *)item->value); if (len1 > item->value_size) { fprintf(stderr, "meta_ape_add_pic_frame: filename too long, discarding\n"); return; } frame = meta_frame_new(); if (frame == NULL) { fprintf(stderr, "meta_ape_add_pic_frame: malloc error\n"); return; } frame->tag = META_TAG_APE; frame->type = META_FIELD_APIC; frame->int_val = meta_ape_pictype_from_string(item->key); frame->field_val = strdup((char *)item->value); frame->length = item->value_size - len1 - 1; frame->data = (unsigned char *)malloc(frame->length); if (frame->data == NULL) { fprintf(stderr, "meta_ape_add_pic_frame: malloc error\n"); meta_frame_free(frame); return; } memcpy(frame->data, item->value + len1 + 1, frame->length); loader = gdk_pixbuf_loader_new(); if (gdk_pixbuf_loader_write(loader, frame->data, frame->length, NULL) != TRUE) { fprintf(stderr, "meta_ape_add_apic_frame: failed to load image #1\n"); meta_frame_free(frame); g_object_unref(loader); return; } if (gdk_pixbuf_loader_close(loader, NULL) != TRUE) { fprintf(stderr, "meta_ape_add_apic_frame: failed to load image #2\n"); meta_frame_free(frame); g_object_unref(loader); return; } format = gdk_pixbuf_loader_get_format(loader); if (format == NULL) { fprintf(stderr, "meta_ape_add_apic_frame: failed to load image #3\n"); meta_frame_free(frame); g_object_unref(loader); return; } mime_types = gdk_pixbuf_format_get_mime_types(format); if (mime_types[0] != NULL) { frame->field_name = strdup(mime_types[0]); g_strfreev(mime_types); } else { fprintf(stderr, "meta_ape_add_apic_frame: error: no mime type for image\n"); g_strfreev(mime_types); meta_frame_free(frame); g_object_unref(loader); return; } g_object_unref(loader); metadata_add_frame(meta, frame); } void meta_ape_add_hidden_frame(metadata_t * meta, ape_item_t * item) { meta_frame_t * frame = meta_frame_new(); frame->tag = META_TAG_APE; frame->type = META_FIELD_HIDDEN; if (APE_FLAG_IS_LOCATOR(item->flags)) { frame->flags |= META_FIELD_LOCATOR; } frame->field_val = strdup((char *)item->key); frame->length = item->value_size; frame->data = malloc(frame->length); if (frame->data == NULL) { fprintf(stderr, "meta_ape_add_hidden_frame: malloc error\n"); return; } memcpy(frame->data, item->value, frame->length); metadata_add_frame(meta, frame); } void meta_add_frame_from_ape_item(metadata_t * meta, ape_item_t * item) { int i; meta_frame_t * frame; if (APE_FLAG_IS_BINARY(item->flags)) { if (strcasestr((char *)item->key, "cover art") == (char *)item->key) { meta_ape_add_pic_frame(meta, item); } else { meta_ape_add_hidden_frame(meta, item); } return; } frame = metadata_add_frame_from_keyval(meta, META_TAG_APE, (char *)item->key, (char *)item->value); if (APE_FLAG_IS_LOCATOR(item->flags)) { frame->flags |= META_FIELD_LOCATOR; } /* handle list of values */ for (i = 1; i < item->value_size; i++) { if (item->value[i-1] == 0x00) { frame = metadata_add_frame_from_keyval(meta, META_TAG_APE, (char *)item->key, (char *)item->value+i); if (APE_FLAG_IS_LOCATOR(item->flags)) { frame->flags |= META_FIELD_LOCATOR; } } } } void metadata_from_ape_tag(metadata_t * meta, ape_tag_t * tag) { GSList * list = tag->items; while (list != NULL) { ape_item_t * item = (ape_item_t *)list->data; meta_add_frame_from_ape_item(meta, item); list = g_slist_next(list); } } void meta_ape_render_apic(meta_frame_t * frame, ape_item_t * item) { int len1 = strlen(frame->field_val); item->value_size = frame->length + len1 + 1; item->value = (unsigned char *)malloc(item->value_size); memcpy(item->value, frame->field_val, len1); (item->value)[len1] = '\0'; memcpy(item->value + len1 + 1, frame->data, frame->length); } void meta_ape_render_bin_frames(metadata_t * meta, ape_tag_t * tag, int type, u_int32_t * item_count, u_int32_t * total_size) { meta_frame_t * frame; frame = metadata_get_frame_by_tag_and_type(meta, META_TAG_APE, type, NULL); while (frame) { char key[255]; ape_item_t * item = meta_ape_item_new(); item->flags = APE_FLAG_BINARY; if ((frame->flags & META_FIELD_LOCATOR) != 0) { item->flags = APE_FLAG_LOCATOR; } switch (type) { case META_FIELD_APIC: snprintf(key, 254, "Cover Art (%s)", meta_id3v2_apic_type_to_string(frame->int_val)); strncpy((char *)item->key, key, 255); meta_ape_render_apic(frame, item); break; case META_FIELD_HIDDEN: strncpy((char *)item->key, frame->field_val, 255); item->value_size = frame->length; item->value = (unsigned char *)malloc(item->value_size); memcpy(item->value, frame->data, item->value_size); break; default: fprintf(stderr, "meta_ape_render_bin_frames: programmer error: unknown frame type %d\n", type); free(item); return; } *total_size += 9 + strlen((char *)item->key) + item->value_size; ++*item_count; tag->items = g_slist_append(tag->items, item); frame = metadata_get_frame_by_tag_and_type(meta, META_TAG_APE, type, frame); } } void metadata_to_ape_tag(metadata_t * meta, ape_tag_t * tag) { GSList * pfields = meta_get_possible_fields(META_TAG_APE); GSList * _pfields = pfields; u_int32_t item_count = 0; u_int32_t total_size = 0; while (pfields != NULL) { int type = GPOINTER_TO_INT(pfields->data); ape_item_t * item; meta_frame_t * frame; char * str; if (META_FIELD_BIN(type)) { meta_ape_render_bin_frames(meta, tag, type, &item_count, &total_size); pfields = g_slist_next(pfields); continue; } frame = metadata_get_frame_by_tag_and_type(meta, META_TAG_APE, type, NULL); if (frame == NULL) { pfields = g_slist_next(pfields); continue; } item = meta_ape_item_new(); if ((frame->flags & META_FIELD_LOCATOR) != 0) { item->flags = APE_FLAG_LOCATOR; } if (meta_get_fieldname_embedded(META_TAG_APE, type, &str)) { strncpy((char *)item->key, str, 255); } else { strncpy((char *)item->key, frame->field_name, 255); } while (frame != NULL) { char fval[MAXLEN]; char * field_val = NULL; int field_len = 0; char * renderfmt = meta_get_field_renderfmt(type); if (META_FIELD_TEXT(type)) { field_val = frame->field_val; field_len = strlen(frame->field_val); } else if (META_FIELD_INT(type)) { snprintf(fval, MAXLEN-1, renderfmt, frame->int_val); field_val = fval; field_len = strlen(field_val); } else if (META_FIELD_FLOAT(type)) { snprintf(fval, MAXLEN-1, renderfmt, frame->float_val); field_val = fval; field_len = strlen(field_val); } item->value = realloc(item->value, item->value_size + field_len + 1); memcpy(item->value + item->value_size, field_val, field_len); item->value[item->value_size + field_len] = 0x00; item->value_size += field_len + 1; frame = metadata_get_frame_by_tag_and_type(meta, META_TAG_APE, type, frame); } --item->value_size; /* cut the last terminating zero */ ++item_count; total_size += 9 + strlen((char *)item->key) + item->value_size; tag->items = g_slist_append(tag->items, item); pfields = g_slist_next(pfields); } tag->header.version = 2000; tag->header.tag_size = total_size + 32; /* don't count the header */ tag->header.item_count = item_count; tag->header.flags = APE_FLAG_HEADER | APE_FLAG_HAS_HEADER; tag->footer = tag->header; tag->footer.flags &= ~APE_FLAG_HEADER; g_slist_free(_pfields); } int meta_ape_render_header(ape_header_t * header, unsigned char * data) { data[0] = 'A'; data[1] = 'P'; data[2] = 'E'; data[3] = 'T'; data[4] = 'A'; data[5] = 'G'; data[6] = 'E'; data[7] = 'X'; meta_write_int32(header->version, data+8); meta_write_int32(header->tag_size, data+12); meta_write_int32(header->item_count, data+16); meta_write_int32(header->flags, data+20); memset(data+24, 0x00, 8); return 32; } int meta_ape_render_item(ape_item_t * item, unsigned char * data) { u_int32_t slen = strlen((char *)item->key); meta_write_int32(item->value_size, data); meta_write_int32(item->flags, data+4); memcpy(data+8, item->key, slen); data[8 + slen] = 0x00; memcpy(data+slen+9, item->value, item->value_size); return 9 + slen + item->value_size; } void meta_ape_render(ape_tag_t * tag, unsigned char * data) { u_int32_t pos = 0; GSList * items = tag->items; pos += meta_ape_render_header(&tag->header, data); while (items != NULL) { ape_item_t * item = (ape_item_t *)items->data; pos += meta_ape_render_item(item, data + pos); items = g_slist_next(items); } meta_ape_render_header(&tag->footer, data + pos); } int meta_ape_rewrite(char * filename, unsigned char * data, unsigned int length) { FILE * file; unsigned char buf[32]; u_int32_t tag_size, flags; long pos; long offset = 0L; int has_id3v1 = 0; unsigned char id3v1[128]; if ((file = fopen(filename, "r+b")) == NULL) { fprintf(stderr, "meta_ape_rewrite: fopen() failed\n"); return META_ERROR_NOT_WRITABLE; } seek_to_footer: if (fseek(file, -32L + offset, SEEK_END) != 0) { fprintf(stderr, "meta_ape_rewrite: fseek() failed\n"); fclose(file); return META_ERROR_INTERNAL; } if (fread(buf, 1, 32, file) != 32) { fprintf(stderr, "meta_ape_rewrite: fread() failed\n"); fclose(file); return META_ERROR_INTERNAL; } if ((buf[0] != 'A') || (buf[1] != 'P') || (buf[2] != 'E') || (buf[3] != 'T') || (buf[4] != 'A') || (buf[5] != 'G') || (buf[6] != 'E') || (buf[7] != 'X')) { if (has_id3v1 == 0) { /* read last 128 bytes of file */ if (fseek(file, -128L, SEEK_END) != 0) { fprintf(stderr, "meta_ape_rewrite: fseek() failed\n"); fclose(file); return META_ERROR_INTERNAL; } if (fread(id3v1, 1, 128, file) != 128) { fprintf(stderr, "meta_ape_rewrite: fread() failed\n"); fclose(file); return META_ERROR_INTERNAL; } if ((id3v1[0] == 'T') && (id3v1[1] == 'A') && (id3v1[2] == 'G')) { has_id3v1 = 1; offset = -128L; goto seek_to_footer; } else { /* no ID3v1, no APE -> append APE */ fseek(file, 0L, SEEK_END); if (data != NULL && length > 0) { if (fwrite(data, 1, length, file) != length) { fprintf(stderr, "meta_ape_rewrite: fwrite() failed\n"); fclose(file); return META_ERROR_INTERNAL; } } goto truncate_ape; } } else { /* we have ID3v1, but no APE -> write APE and append ID3v1 */ fseek(file, -128L, SEEK_END); if (data != NULL && length > 0) { if (fwrite(data, 1, length, file) != length) { fprintf(stderr, "meta_ape_rewrite: fwrite() failed\n"); fclose(file); return META_ERROR_INTERNAL; } } if (fwrite(id3v1, 1, 128, file) != 128) { fprintf(stderr, "meta_ape_rewrite: fwrite() failed\n"); fclose(file); return META_ERROR_INTERNAL; } goto truncate_ape; } } /* overwrite existing APE tag, and append ID3v1 if we have it */ tag_size = meta_read_int32(buf+12); flags = meta_read_int32(buf+20); pos = offset -(long)tag_size; if ((flags & APE_FLAG_HAS_HEADER) != 0) { pos -= 32; } if (fseek(file, pos, SEEK_END) != 0) { fprintf(stderr, "meta_ape_rewrite: fseek() failed\n"); fclose(file); return META_ERROR_INTERNAL; } if (data != NULL && length > 0) { if (fwrite(data, 1, length, file) != length) { fprintf(stderr, "meta_ape_rewrite: fwrite() failed\n"); fclose(file); return META_ERROR_INTERNAL; } } if (has_id3v1) { if (fwrite(id3v1, 1, 128, file) != 128) { fprintf(stderr, "meta_ape_rewrite: fwrite() failed\n"); fclose(file); return META_ERROR_INTERNAL; } } truncate_ape: pos = ftell(file); fclose(file); if (truncate(filename, pos) < 0) { fprintf(stderr, "meta_ape_rewrite: truncate() failed on %s\n", filename); return META_ERROR_INTERNAL; } return META_ERROR_NONE; } int meta_ape_delete(char * filename) { return meta_ape_rewrite(filename, NULL, 0); } int meta_ape_replace_or_append(char * filename, ape_tag_t * tag) { int ret; unsigned char * data = calloc(1, tag->header.tag_size + 32); if (data == NULL) { fprintf(stderr, "meta_ape_replace_or_append: calloc error\n"); } meta_ape_render(tag, data); ret = meta_ape_rewrite(filename, data, tag->header.tag_size + 32); free(data); return ret; } int meta_ape_write_metadata(file_decoder_t * fdec, metadata_t * meta) { int ret; ape_tag_t tag; memset(&tag, 0x00, sizeof(ape_tag_t)); metadata_to_ape_tag(meta, &tag); if (tag.header.item_count > 0) { ret = meta_ape_replace_or_append(fdec->filename, &tag); } else { ret = meta_ape_delete(fdec->filename); } meta_ape_free(&tag); return ret; } void meta_ape_send_metadata(metadata_t * meta, file_decoder_t * fdec) { ape_tag_t tag; if (meta == NULL) { return; } memset(&tag, 0x00, sizeof(ape_tag_t)); if (meta_ape_parse(fdec->filename, &tag)) { metadata_from_ape_tag(meta, &tag); meta_ape_free(&tag); } meta->valid_tags |= META_TAG_APE; if (access(fdec->filename, R_OK | W_OK) == 0) { meta->writable = 1; fdec->meta_write = meta_ape_write_metadata; } else { meta->writable = 0; } meta->fdec = fdec; fdec->meta = meta; if (fdec->meta_cb != NULL) { fdec->meta_cb(meta, fdec->meta_cbdata); } } aqualung-0.9beta11/src/metadata_flac.h0000644000175000001440000000302710713134045014617 00000000000000/* -*- linux-c -*- Copyright (C) 2007 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: metadata_flac.h 868 2007-11-03 17:00:08Z tszilagyi $ */ #ifndef _METADATA_FLAC_H #define _METADATA_FLAC_H #include #ifdef HAVE_FLAC #include #endif /* HAVE_FLAC */ #include #include "common.h" #include "metadata.h" #ifdef HAVE_FLAC void metadata_from_flac_streammeta_vc(metadata_t * meta, FLAC__StreamMetadata_VorbisComment * vc); FLAC__StreamMetadata * metadata_to_flac_streammeta(metadata_t * meta); #ifdef HAVE_FLAC_8 void metadata_from_flac_streammeta_pic(metadata_t * meta, FLAC__StreamMetadata_Picture * pic); FLAC__StreamMetadata * metadata_apic_frame_to_smeta(meta_frame_t * frame); #endif /* HAVE_FLAC_8 */ #endif /* HAVE_FLAC */ #endif /* _METADATA_FLAC_H */ aqualung-0.9beta11/src/metadata_flac.c0000644000175000001440000001155510713134045014617 00000000000000/* -*- linux-c -*- Copyright (C) 2007 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: metadata_flac.c 868 2007-11-03 17:00:08Z tszilagyi $ */ #include #include #include #include #include #include #include #include "common.h" #include "i18n.h" #include "metadata_flac.h" #ifdef HAVE_FLAC void metadata_from_flac_streammeta_vc(metadata_t * meta, FLAC__StreamMetadata_VorbisComment * vc) { int i; if (!meta || !vc) { return; } for (i = 0; i < vc->num_comments; i++) { char key[MAXLEN]; char val[MAXLEN]; char c; int k, n = 0; for (k = 0; ((c = vc->comments[i].entry[n]) != '=') && (n < vc->comments[i].length) && (k < MAXLEN-1); k++) { key[k] = (k == 0) ? toupper(c) : tolower(c); ++n; } key[k] = '\0'; ++n; for (k = 0; (n < vc->comments[i].length) && (k < MAXLEN-1); k++) { val[k] = vc->comments[i].entry[n]; ++n; } val[k] = '\0'; metadata_add_frame_from_keyval(meta, META_TAG_OXC, key, val); } /* Add Vendor string */ metadata_add_frame_from_keyval(meta, META_TAG_OXC, "vendor", (vc->vendor_string.length > 0) ? (char *)vc->vendor_string.entry : ""); } #ifdef HAVE_FLAC_8 void metadata_from_flac_streammeta_pic(metadata_t * meta, FLAC__StreamMetadata_Picture * pic) { meta_frame_t * frame = meta_frame_new(); if (frame == NULL) { return; } frame->tag = META_TAG_FLAC_APIC; frame->type = META_FIELD_APIC; frame->field_name = strdup(pic->mime_type); frame->field_val = strdup((char *)pic->description); frame->int_val = pic->type; frame->length = pic->data_length; frame->data = (unsigned char *)malloc(frame->length); if (frame->data == NULL) { meta_frame_free(frame); return; } memcpy(frame->data, pic->data, frame->length); metadata_add_frame(meta, frame); } #endif /* HAVE_FLAC_8 */ void meta_entry_from_frame(FLAC__StreamMetadata_VorbisComment_Entry * entry, meta_frame_t * frame) { char * key = NULL; char * val = NULL; char * renderfmt = meta_get_field_renderfmt(frame->type); char str[MAXLEN]; if (!meta_get_fieldname_embedded(META_TAG_OXC, frame->type, &key)) { key = g_ascii_strdown(frame->field_name, strlen(frame->field_name)); free(frame->field_name); frame->field_name = key; } if (META_FIELD_TEXT(frame->type)) { val = frame->field_val; } else if (META_FIELD_INT(frame->type)) { snprintf(str, MAXLEN-1, renderfmt, frame->int_val); val = str; } else if (META_FIELD_FLOAT(frame->type)) { snprintf(str, MAXLEN-1, renderfmt, frame->float_val); val = str; } else { fprintf(stderr, "meta_entry_from_frame: frame type 0x%x is unsupported\n", frame->type); } FLAC__metadata_object_vorbiscomment_entry_from_name_value_pair( entry, key, val); } FLAC__StreamMetadata * metadata_to_flac_streammeta(metadata_t * meta) { FLAC__StreamMetadata * smeta = FLAC__metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT); meta_frame_t * frame = metadata_get_frame_by_tag(meta, META_TAG_OXC, NULL); while (frame != NULL) { if (frame->type == META_FIELD_VENDOR) { FLAC__StreamMetadata_VorbisComment_Entry entry; entry.entry = (unsigned char *)strdup(frame->field_val); entry.length = strlen(frame->field_val); FLAC__metadata_object_vorbiscomment_set_vendor_string( smeta, entry, false); } else { FLAC__StreamMetadata_VorbisComment_Entry entry; meta_entry_from_frame(&entry, frame); FLAC__metadata_object_vorbiscomment_insert_comment( smeta, smeta->data.vorbis_comment.num_comments, entry, false); } frame = metadata_get_frame_by_tag(meta, META_TAG_OXC, frame); } return smeta; } #ifdef HAVE_FLAC_8 FLAC__StreamMetadata * metadata_apic_frame_to_smeta(meta_frame_t * frame) { FLAC__StreamMetadata * smeta = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PICTURE); FLAC__metadata_object_picture_set_mime_type(smeta, frame->field_name, true); FLAC__metadata_object_picture_set_description(smeta, (unsigned char *)frame->field_val, true); FLAC__metadata_object_picture_set_data(smeta, frame->data, frame->length, true); smeta->data.picture.type = frame->int_val; return smeta; } #endif /* HAVE_FLAC_8 */ #endif /* HAVE_FLAC */ aqualung-0.9beta11/src/metadata_id3v1.h0000644000175000001440000000276310665075115014656 00000000000000/* -*- linux-c -*- Copyright (C) 2007 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: metadata_id3v1.h 803 2007-08-28 19:37:50Z tszilagyi $ */ #ifndef _METADATA_ID3V1_H #define _METADATA_ID3V1_H #include #include #include "common.h" #include "metadata.h" char * id3v1_genre_str_from_code(int code); int id3v1_genre_code_from_str(char * str); /* these return a newly allocated string, or NULL */ char * meta_id3v1_utf8_to_tagenc(char * utf8); char * meta_id3v1_utf8_from_tagenc(char * tagenc); int metadata_from_id3v1(metadata_t * meta, unsigned char * buf); int metadata_to_id3v1(metadata_t * meta, unsigned char * buf); int meta_id3v1_delete(char * filename); int meta_id3v1_rewrite(char * filename, unsigned char * id3v1); #endif /* _METADATA_ID3V1_H */ aqualung-0.9beta11/src/metadata_id3v1.c0000644000175000001440000003226510727033063014644 00000000000000/* -*- linux-c -*- Copyright (C) 2007 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: metadata_id3v1.c 908 2007-12-07 12:05:01Z tszilagyi $ */ #include #include #include #include #include #include #include #include "common.h" #include "utils.h" #include "i18n.h" #include "metadata.h" #include "metadata_api.h" #include "metadata_id3v1.h" char * id3v1_genre_str_from_code(int code) { switch (code) { /* Standard ID3v1 */ case 0: return "Blues"; case 1: return "Classic Rock"; case 2: return "Country"; case 3: return "Dance"; case 4: return "Disco"; case 5: return "Funk"; case 6: return "Grunge"; case 7: return "Hip-Hop"; case 8: return "Jazz"; case 9: return "Metal"; case 10: return "New Age"; case 11: return "Oldies"; case 12: return "Other"; case 13: return "Pop"; case 14: return "R&B"; case 15: return "Rap"; case 16: return "Reggae"; case 17: return "Rock"; case 18: return "Techno"; case 19: return "Industrial"; case 20: return "Alternative"; case 21: return "Ska"; case 22: return "Death Metal"; case 23: return "Pranks"; case 24: return "Soundtrack"; case 25: return "Euro-Techno"; case 26: return "Ambient"; case 27: return "Trip-Hop"; case 28: return "Vocal"; case 29: return "Jazz+Funk"; case 30: return "Fusion"; case 31: return "Trance"; case 32: return "Classical"; case 33: return "Instrumental"; case 34: return "Acid"; case 35: return "House"; case 36: return "Game"; case 37: return "Sound Clip"; case 38: return "Gospel"; case 39: return "Noise"; case 40: return "AlternRock"; case 41: return "Bass"; case 42: return "Soul"; case 43: return "Punk"; case 44: return "Space"; case 45: return "Meditative"; case 46: return "Instrumental Pop"; case 47: return "Instrumental Rock"; case 48: return "Ethnic"; case 49: return "Gothic"; case 50: return "Darkwave"; case 51: return "Techno-Industrial"; case 52: return "Electronic"; case 53: return "Pop-Folk"; case 54: return "Eurodance"; case 55: return "Dream"; case 56: return "Southern Rock"; case 57: return "Comedy"; case 58: return "Cult"; case 59: return "Gangsta"; case 60: return "Top 40"; case 61: return "Christian Rap"; case 62: return "Pop/Funk"; case 63: return "Jungle"; case 64: return "Native American"; case 65: return "Cabaret"; case 66: return "New Wave"; case 67: return "Psychadelic"; case 68: return "Rave"; case 69: return "Showtunes"; case 70: return "Trailer"; case 71: return "Lo-Fi"; case 72: return "Tribal"; case 73: return "Acid Punk"; case 74: return "Acid Jazz"; case 75: return "Polka"; case 76: return "Retro"; case 77: return "Musical"; case 78: return "Rock & Roll"; case 79: return "Hard Rock"; /* Winamp extensions */ case 80: return "Folk"; case 81: return "Folk-Rock"; case 82: return "National Folk"; case 83: return "Swing"; case 84: return "Fast Fusion"; case 85: return "Bebob"; case 86: return "Latin"; case 87: return "Revival"; case 88: return "Celtic"; case 89: return "Bluegrass"; case 90: return "Avantgarde"; case 91: return "Gothic Rock"; case 92: return "Progressive Rock"; case 93: return "Psychedelic Rock"; case 94: return "Symphonic Rock"; case 95: return "Slow Rock"; case 96: return "Big Band"; case 97: return "Chorus"; case 98: return "Easy Listening"; case 99: return "Acoustic"; case 100: return "Humour"; case 101: return "Speech"; case 102: return "Chanson"; case 103: return "Opera"; case 104: return "Chamber Music"; case 105: return "Sonata"; case 106: return "Symphony"; case 107: return "Booty Bass"; case 108: return "Primus"; case 109: return "Porn Groove"; case 110: return "Satire"; case 111: return "Slow Jam"; case 112: return "Club"; case 113: return "Tango"; case 114: return "Samba"; case 115: return "Folklore"; case 116: return "Ballad"; case 117: return "Power Ballad"; case 118: return "Rhythmic Soul"; case 119: return "Freestyle"; case 120: return "Duet"; case 121: return "Punk Rock"; case 122: return "Drum Solo"; case 123: return "A capella"; case 124: return "Euro-House"; case 125: return "Dance Hall"; case 126: return "Goa"; case 127: return "Drum & Bass"; case 128: return "Club-House"; case 129: return "Hardcore"; case 130: return "Terror"; case 131: return "Indie"; case 132: return "BritPop"; case 133: return "Negerpunk"; case 134: return "Polsk Punk"; case 135: return "Beat"; case 136: return "Christian"; case 137: return "Heavy Metal"; case 138: return "Black Metal"; case 139: return "Crossover"; case 140: return "Contemporary"; case 141: return "Christian Rock"; case 142: return "Merengue"; case 143: return "Salsa"; case 144: return "Thrash Metal"; case 145: return "Anime"; case 146: return "JPop"; case 147: return "Synthpop"; default: return NULL; } } /* ret: -1 if not found */ int id3v1_genre_code_from_str(char * str) { int i; for (i = 0; i < 256; i++) { char * lookup = id3v1_genre_str_from_code(i); if (lookup == NULL) { return -1; } if (strcmp(lookup, str) == 0) { return i; } } return -1; } char * meta_id3v1_utf8_to_tagenc(char * utf8) { char * str = NULL; GError * error = NULL; /* convert to iso-8859-1 */ str = g_convert_with_fallback(utf8, -1, "iso-8859-1", "utf-8", "?", NULL, NULL, &error); if (str != NULL) { return str; } else { fprintf(stderr, "meta_id3v1_utf8_to_tagenc: error converting '%s': %s\n", utf8, error->message); g_clear_error(&error); return NULL; } } char * meta_id3v1_utf8_from_tagenc(char * tagenc) { char * str = NULL; GError * error = NULL; /* try to use string as utf8, convert from iso-8859-1 if that fails. */ if (g_utf8_validate(tagenc, -1, NULL)) { return g_strdup(tagenc); } else { g_clear_error(&error); str = g_convert_with_fallback(tagenc, -1, "utf-8", "iso-8859-1", "?", NULL, NULL, &error); if (str != NULL) { return str; } else { fprintf(stderr, "meta_id3v1_utf8_from_tagenc: error converting '%s': %s\n", tagenc, error->message); g_clear_error(&error); return NULL; } } } void meta_add_id3v1_frame(metadata_t * meta, char * key, char * val) { char * str = meta_id3v1_utf8_from_tagenc(val); if (str == NULL) { return; } metadata_add_frame_from_keyval(meta, META_TAG_ID3v1, key, str); g_free(str); } int metadata_from_id3v1(metadata_t * meta, unsigned char * buf) { char raw[31]; char * genre; if ((buf[0] != 'T') || (buf[1] != 'A') || (buf[2] != 'G')) { return 0; } raw[30] = '\0'; if(buf[3] != '\0') { memcpy(raw, buf+3, 30); cut_trailing_whitespace(raw); meta_add_id3v1_frame(meta, "Title", raw); } if(buf[33] != '\0') { memcpy(raw, buf+33, 30); cut_trailing_whitespace(raw); meta_add_id3v1_frame(meta, "Artist", raw); } if(buf[63] != '\0') { memcpy(raw, buf+63, 30); cut_trailing_whitespace(raw); meta_add_id3v1_frame(meta, "Album", raw); } if(buf[93] != '\0') { memcpy(raw, buf+93, 4); raw[4] = '\0'; cut_trailing_whitespace(raw); meta_add_id3v1_frame(meta, "Year", raw); } memcpy(raw, buf+97, 30); if ((raw[28] == '\0') && (raw[29] != '\0')) { /* ID3v1.1 */ char track[4]; snprintf(track, 4, "%u", (unsigned char)raw[29]); meta_add_id3v1_frame(meta, "Track", track); } genre = id3v1_genre_str_from_code(buf[127]); if (genre != NULL) { meta_add_id3v1_frame(meta, "Genre", genre); } if(buf[97] != '\0') { cut_trailing_whitespace(raw); meta_add_id3v1_frame(meta, "Comment", raw); } return 1; } int metadata_to_id3v1(metadata_t * meta, unsigned char * buf) { meta_frame_t * frame; int has_trackno = 0; buf[0] = 'T'; buf[1] = 'A'; buf[2] = 'G'; memset(buf+3, 0x00, 125); frame = metadata_get_frame_by_tag_and_type(meta, META_TAG_ID3v1, META_FIELD_TITLE, NULL); if (frame != NULL) { char * str = meta_id3v1_utf8_to_tagenc(frame->field_val); if (str != NULL) { strncpy((char *)buf+3, str, 30); g_free(str); } else { return META_ERROR_INVALID_CODING; } } frame = metadata_get_frame_by_tag_and_type(meta, META_TAG_ID3v1, META_FIELD_ARTIST, NULL); if (frame != NULL) { char * str = meta_id3v1_utf8_to_tagenc(frame->field_val); if (str != NULL) { strncpy((char *)buf+33, str, 30); g_free(str); } else { return META_ERROR_INVALID_CODING; } } frame = metadata_get_frame_by_tag_and_type(meta, META_TAG_ID3v1, META_FIELD_ALBUM, NULL); if (frame != NULL) { char * str = meta_id3v1_utf8_to_tagenc(frame->field_val); if (str != NULL) { strncpy((char *)buf+63, str, 30); g_free(str); } else { return META_ERROR_INVALID_CODING; } } frame = metadata_get_frame_by_tag_and_type(meta, META_TAG_ID3v1, META_FIELD_DATE, NULL); if (frame != NULL) { char * str = meta_id3v1_utf8_to_tagenc(frame->field_val); if (str != NULL) { strncpy((char *)buf+93, str, 4); g_free(str); } else { return META_ERROR_INVALID_CODING; } } frame = metadata_get_frame_by_tag_and_type(meta, META_TAG_ID3v1, META_FIELD_TRACKNO, NULL); if (frame != NULL) { if (frame->int_val == 0) { fprintf(stderr, "error: Track no. 0 in ID3v1 is not possible.\n"); return META_ERROR_INVALID_TRACKNO; } else if (frame->int_val > 255) { fprintf(stderr, "error: Track no. %d > 255 in ID3v1 is not possible (does not fit on one byte).\n", frame->int_val); return META_ERROR_INVALID_TRACKNO; } else { buf[126] = (unsigned char)frame->int_val; has_trackno = 1; } } frame = metadata_get_frame_by_tag_and_type(meta, META_TAG_ID3v1, META_FIELD_GENRE, NULL); if (frame != NULL) { int genre = id3v1_genre_code_from_str(frame->field_val); if (genre != -1) { buf[127] = genre; } else { fprintf(stderr, "error: Genre '%s' is not supported by ID3v1.\n", frame->field_val); return META_ERROR_INVALID_GENRE; } } frame = metadata_get_frame_by_tag_and_type(meta, META_TAG_ID3v1, META_FIELD_COMMENT, NULL); if (frame != NULL) { char * str = meta_id3v1_utf8_to_tagenc(frame->field_val); if (str != NULL) { strncpy((char *)buf+97, str, has_trackno ? 28 : 30); g_free(str); } else { return META_ERROR_INVALID_CODING; } } return META_ERROR_NONE; } int meta_id3v1_delete(char * filename) { FILE * file; unsigned char id3v1_file[128]; long pos; if ((file = fopen(filename, "r+b")) == NULL) { fprintf(stderr, "meta_id3v1_delete: fopen() failed\n"); return META_ERROR_NOT_WRITABLE; } if (fseek(file, -128L, SEEK_END) != 0) { fprintf(stderr, "meta_id3v1_delete: fseek() failed\n"); fclose(file); return META_ERROR_INTERNAL; } if (fread(id3v1_file, 1, 128, file) != 128) { fprintf(stderr, "meta_id3v1_delete: fread() failed\n"); fclose(file); return META_ERROR_INTERNAL; } if ((id3v1_file[0] == 'T') && (id3v1_file[1] == 'A') && (id3v1_file[2] == 'G')) { /* seek back to beginning of tag */ if (fseek(file, -128L, SEEK_END) != 0) { fprintf(stderr, "meta_id3v1_delete: fseek() failed\n"); fclose(file); return META_ERROR_INTERNAL; } } else { /* seek to the end of file */ if (fseek(file, 0L, SEEK_END) != 0) { fprintf(stderr, "meta_id3v1_delete: fseek() failed\n"); fclose(file); return META_ERROR_INTERNAL; } } pos = ftell(file); fclose(file); if (truncate(filename, pos) < 0) { fprintf(stderr, "meta_ape_rewrite: truncate() failed on %s\n", filename); return META_ERROR_INTERNAL; } return META_ERROR_NONE; } int meta_id3v1_rewrite(char * filename, unsigned char * id3v1) { FILE * file; unsigned char id3v1_file[128]; if ((file = fopen(filename, "r+b")) == NULL) { fprintf(stderr, "meta_id3v1_rewrite: fopen() failed\n"); return META_ERROR_NOT_WRITABLE; } if (fseek(file, -128L, SEEK_END) != 0) { fprintf(stderr, "meta_id3v1_rewrite: fseek() failed\n"); fclose(file); return META_ERROR_INTERNAL; } if (fread(id3v1_file, 1, 128, file) != 128) { fprintf(stderr, "meta_id3v1_rewrite: fread() failed\n"); fclose(file); return META_ERROR_INTERNAL; } if ((id3v1_file[0] == 'T') && (id3v1_file[1] == 'A') && (id3v1_file[2] == 'G')) { /* seek back to beginning of tag so it gets overwritten */ if (fseek(file, -128L, SEEK_END) != 0) { fprintf(stderr, "meta_id3v1_rewrite: fseek() failed\n"); fclose(file); return META_ERROR_INTERNAL; } } else { /* seek to the end of file to append tag */ if (fseek(file, 0L, SEEK_END) != 0) { fprintf(stderr, "meta_id3v1_rewrite: fseek() failed\n"); fclose(file); return META_ERROR_INTERNAL; } } /* write new tag */ if (fwrite(id3v1, 1, 128, file) != 128) { fprintf(stderr, "meta_id3v1_rewrite: fwrite() failed\n"); fclose(file); return META_ERROR_INTERNAL; } fclose(file); return META_ERROR_NONE; } aqualung-0.9beta11/src/metadata_id3v2.h0000644000175000001440000000332010712330740014634 00000000000000/* -*- linux-c -*- Copyright (C) 2007 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: metadata_id3v2.h 859 2007-11-01 09:56:37Z tszilagyi $ */ #ifndef _METADATA_ID3V2_H #define _METADATA_ID3V2_H #include #include #include "common.h" #include "metadata.h" char * meta_id3v2_apic_type_to_string(int type); u_int32_t meta_id3v2_read_int(unsigned char * buf); u_int32_t meta_id3v2_read_synchsafe_int(unsigned char * buf); int metadata_from_id3v2(metadata_t * meta, unsigned char * buf, int length); int metadata_to_id3v2(metadata_t * meta, unsigned char ** data, int * length); char * meta_id3v2_to_utf8(unsigned char enc, unsigned char * buf, int len); int meta_id3v2_padding_size(int size); void meta_id3v2_pad(unsigned char ** buf, int * size, int padded_size); int meta_id3v2_write_tag(FILE * file, unsigned char * buf, int len); int meta_id3v2_delete(char * filename); int meta_id3v2_rewrite(char * filename, unsigned char ** buf, int * len); #endif /* _METADATA_ID3V2_H */ aqualung-0.9beta11/src/metadata_id3v2.c0000644000175000001440000007252610734276334014661 00000000000000/* -*- linux-c -*- Copyright (C) 2007 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: metadata_id3v2.c 958 2007-12-25 21:57:50Z tszilagyi $ */ #include #include #include #include #include #include #include #include "common.h" #include "utils.h" #include "i18n.h" #include "metadata.h" #include "metadata_api.h" #include "metadata_id3v2.h" char * meta_id3v2_apic_type_to_string(int type) { switch (type) { case 0x00: return _("Other"); case 0x01: return _("File icon (32x32 PNG)"); case 0x02: return _("File icon (other)"); case 0x03: return _("Front cover"); case 0x04: return _("Back cover"); case 0x05: return _("Leaflet page"); case 0x06: return _("Album image"); case 0x07: return _("Lead artist/performer"); case 0x08: return _("Artist/performer"); case 0x09: return _("Conductor"); case 0x0a: return _("Band/orchestra"); case 0x0b: return _("Composer"); case 0x0c: return _("Lyricist/text writer"); case 0x0d: return _("Recording location/studio"); case 0x0e: return _("During recording"); case 0x0f: return _("During performance"); case 0x10: return _("Movie/video screen capture"); case 0x11: return _("A large, coloured fish"); case 0x12: return _("Illustration"); case 0x13: return _("Band/artist logotype"); case 0x14: return _("Publisher/studio logotype"); default: return NULL; } } /* strlen() for ID3v2 strings. * enc={0,3} -> terminated by one null-byte * enc={1,2} -> terminated by two null-bytes * buf is traversed to a maximum of buf[maxlen]. */ int meta_id3v2_strlen(unsigned char * buf, int maxlen, int enc) { int i; for (i = 0; i < maxlen; i++) { if (buf[i] == '\0') { if ((enc == 0) || (enc == 3)) { return i; } if ((enc == 1) || (enc == 2)) { if ((i > 0) && (buf[i-1] == '\0')) { return i; } } } } return maxlen; } u_int32_t meta_id3v2_read_int(unsigned char * buf) { return ((((u_int32_t)buf[0]) << 24) | (((u_int32_t)buf[1]) << 16) | (((u_int32_t)buf[2]) << 8) | (u_int32_t)buf[3]); } u_int32_t meta_id3v2_read_synchsafe_int(unsigned char * buf) { return (((u_int32_t)(buf[0] & 0x7f) << 21) | ((u_int32_t)(buf[1] & 0x7f) << 14) | ((u_int32_t)(buf[2] & 0x7f) << 7) | (u_int32_t)(buf[3] & 0x7f)); } void meta_id3v2_write_synchsafe_int(unsigned char * buf, u_int32_t val) { buf[0] = ((val >> 21) & 0x7f); buf[1] = ((val >> 14) & 0x7f); buf[2] = ((val >> 7) & 0x7f); buf[3] = (val & 0x7f); } void unsynch(unsigned char * inbuf, int inlen, unsigned char ** outbuf, int * outlen) { int i; int outpos = 0; *outlen = inlen; *outbuf = (unsigned char *)malloc(*outlen); if (*outbuf == NULL) { fprintf(stderr, "unsynch(): malloc error"); return; } for (i = 0; i < inlen; i++) { if ((i > 0) && (inbuf[i-1] == 0xff) && (((inbuf[i] & 0xe0) == 0xe0) || (inbuf[i] == 0x0))) { *outlen += 1; *outbuf = (unsigned char *)realloc(*outbuf, *outlen); if (*outbuf == NULL) { fprintf(stderr, "unsynch(): realloc error"); return; } (*outbuf)[outpos++] = 0x0; } (*outbuf)[outpos++] = inbuf[i]; } } int un_unsynch(unsigned char * buf, int len) { int i; for (i = 0; i < len-1; i++) { if ((buf[i] == 0xff) && (buf[i+1] == 0x00)) { memmove(buf+i+1, buf+i+2, len-i-2); --len; } } return len; } char * meta_id3v2_to_utf8(unsigned char enc, unsigned char * buf, int len) { char * str = NULL; char * from; GError * error = NULL; if (buf[0] == '\0') { return strdup(""); } switch (enc) { case 0x00: from = "iso-8859-1"; break; case 0x01: from = "utf-16"; break; case 0x02: from = "utf-16be"; break; case 0x03: from = "utf-8"; break; default: fprintf(stderr, "meta_id3v2_to_utf8: invalid enc = %d\n", enc); return NULL; } str = g_convert_with_fallback((char *)buf, len, "utf-8", from, "?", NULL, NULL, &error); if (str != NULL) { return str; } else { fprintf(stderr, "meta_id3v2_to_utf8: error converting '%s': %s\n", buf, error->message); g_clear_error(&error); return NULL; } } char * meta_id3v2_latin1_from_utf8(char * buf, int len) { char * str = NULL; GError * error = NULL; if (buf[0] == '\0') { return strdup(""); } str = g_convert_with_fallback((char *)buf, len, "iso-8859-1", "utf-8", "?", NULL, NULL, &error); if (str != NULL) { return str; } else { fprintf(stderr, "meta_id3v2_latin1_from_utf8: error converting '%s': %s\n", buf, error->message); g_clear_error(&error); return NULL; } } void meta_parse_id3v2_txxx(metadata_t * meta, unsigned char * buf, int len) { int type; int len1; char * val1; char * val2; type = meta_frame_type_from_embedded_name(META_TAG_ID3v2, "TXXX"); len1 = meta_id3v2_strlen(buf+11, len-1, buf[10]); val1 = meta_id3v2_to_utf8(buf[10], buf+11, len1); val2 = meta_id3v2_to_utf8(buf[10], buf+12+len1, len-len1-2); if ((val1 != NULL) && (val2 != NULL)) { meta_frame_t * frame = metadata_add_frame_from_keyval(meta, META_TAG_ID3v2, val1, val2); frame->type = META_FIELD_TXXX; } if (val1 != NULL) { g_free(val1); } if (val2 != NULL) { g_free(val2); } } void meta_parse_id3v2_t___(metadata_t * meta, unsigned char * buf, int len) { char frame_id[5]; int type; char * val; memcpy(frame_id, buf, 4); frame_id[4] = '\0'; /* support the reading of some ID3v2.3 fields by mapping them to the respective ID3v2.4 frame */ if ((strcmp(frame_id, "TDAT") == 0) || (strcmp(frame_id, "TIME") == 0) || (strcmp(frame_id, "TRDA") == 0) || (strcmp(frame_id, "TYER") == 0)) { strcpy(frame_id, "TDRC"); } else if (strcmp(frame_id, "TORY") == 0) { strcpy(frame_id, "TDOR"); } type = meta_frame_type_from_embedded_name(META_TAG_ID3v2, frame_id); val = meta_id3v2_to_utf8(buf[10], buf+11, len-1); if (val != NULL) { metadata_add_frame_from_keyval(meta, META_TAG_ID3v2, frame_id, val); g_free(val); } } void meta_parse_id3v2_wxxx(metadata_t * meta, unsigned char * buf, int len) { int type; int len1; char * val1; char * val2; type = meta_frame_type_from_embedded_name(META_TAG_ID3v2, "WXXX"); len1 = meta_id3v2_strlen(buf+11, len-1, buf[10]); val1 = meta_id3v2_to_utf8(buf[10], buf+11, len1); val2 = meta_id3v2_to_utf8(0x0 /* iso-8859-1 */, buf+12+len1, len-len1-2); if ((val1 != NULL) && (val2 != NULL)) { meta_frame_t * frame = metadata_add_frame_from_keyval(meta, META_TAG_ID3v2, val1, val2); frame->type = META_FIELD_WXXX; } if (val1 != NULL) { g_free(val1); } if (val2 != NULL) { g_free(val2); } } void meta_parse_id3v2_w___(metadata_t * meta, unsigned char * buf, int len) { char frame_id[5]; int type; char * val; memcpy(frame_id, buf, 4); frame_id[4] = '\0'; type = meta_frame_type_from_embedded_name(META_TAG_ID3v2, frame_id); val = meta_id3v2_to_utf8(0x0 /* iso-8859-1 */, buf+10, len); if (val != NULL) { metadata_add_frame_from_keyval(meta, META_TAG_ID3v2, frame_id, val); g_free(val); } } void meta_parse_id3v2_comm(metadata_t * meta, unsigned char * buf, int len) { char enc = buf[10]; char lang[4]; int len1; char * descr; char * comment = NULL; memcpy(lang, buf+11, 3); lang[3] = '\0'; len1 = meta_id3v2_strlen(buf+14, len-4, enc); if (len1 > len - 4) { len1 = len-4; fprintf(stderr, "warning: COMM description field too large, truncating\n"); } descr = meta_id3v2_to_utf8(enc, buf+14, len1); if (len - len1 - 4 > 0) { comment = meta_id3v2_to_utf8(enc, buf+15+len1, len-len1-5); } if (descr != NULL) { g_free(descr); } if (comment != NULL) { metadata_add_frame_from_keyval(meta, META_TAG_ID3v2, "COMM", comment); g_free(comment); } } void meta_parse_id3v2_apic(metadata_t * meta, unsigned char * buf, int len) { char enc = buf[10]; char * mime_type; char * descr; char pic_type; int len1; int len2; len1 = meta_id3v2_strlen(buf+11, len-1, 0x0/*ascii*/); if (len1 > len-1) { len1 = len-1; fprintf(stderr, "warning: APIC mime-type field too large, truncating\n"); } mime_type = meta_id3v2_to_utf8(0x0/*ascii*/, buf+11, len1); pic_type = buf[12+len1]; len2 = meta_id3v2_strlen(buf+13+len1, len-3-len1, enc); descr = meta_id3v2_to_utf8(enc, buf+13+len1, len2); if ((mime_type != NULL) && (descr != NULL)) { meta_frame_t * frame = meta_frame_new(); frame->tag = META_TAG_ID3v2; frame->type = META_FIELD_APIC; frame->field_name = strdup(mime_type); frame->field_val = strdup(descr); frame->int_val = pic_type; frame->length = len - (4+len1+len2); if (frame->length > 0) { frame->data = malloc(frame->length); if (frame->data == NULL) { fprintf(stderr, "meta_parse_id3v2_apic: malloc error\n"); return; } memcpy(frame->data, buf+14+len1+len2, frame->length); } metadata_add_frame(meta, frame); } if (mime_type != NULL) { g_free(mime_type); } if (descr != NULL) { g_free(descr); } } void meta_parse_id3v2_rva2(metadata_t * meta, unsigned char * buf, int len) { char * id; int len1; int pos; len1 = meta_id3v2_strlen(buf+10, len, 0x0/*ascii*/); if (len1 > len) { len1 = len; fprintf(stderr, "warning: RVA2 identification field too large, truncating\n"); } id = meta_id3v2_to_utf8(0x0/*ascii*/, buf+10, len1); pos = 11 + len1; len -= len1 + 1; while (len >= 4) { unsigned int peak_bytes = (buf[pos+3] + 7) / 8; if (4 + peak_bytes > len) break; if (buf[pos] == 0x01 /* MasterVolume */) { signed int voladj_fixed; double voladj_float; char * field_name; char str[MAXLEN]; meta_frame_t * frame; voladj_fixed = (buf[pos+1] << 8) | (buf[pos+2] << 0); voladj_fixed |= -(voladj_fixed & 0x8000); voladj_float = (double) voladj_fixed / 512.0; frame = meta_frame_new(); frame->tag = META_TAG_ID3v2; frame->type = META_FIELD_RVA2; meta_get_fieldname(META_FIELD_RVA2, &field_name); snprintf(str, MAXLEN-1, "%s (%s)", field_name, id); frame->field_name = strdup(str); frame->field_val = strdup(id); frame->float_val = voladj_float; metadata_add_frame(meta, frame); if (id != NULL) { g_free(id); } return; } pos += 4 + peak_bytes; len -= 4 + peak_bytes; } if (id != NULL) { g_free(id); } } void meta_parse_id3v2_hidden(metadata_t * meta, unsigned char * buf, int len) { meta_frame_t * frame = meta_frame_new(); frame->tag = META_TAG_ID3v2; frame->type = META_FIELD_HIDDEN; frame->length = len+10; frame->data = malloc(frame->length); if (frame->data == NULL) { fprintf(stderr, "meta_parse_id3v2_hidden: malloc error\n"); return; } memcpy(frame->data, buf, frame->length); metadata_add_frame(meta, frame); } int is_frame_char(char c) { return (((c >= 'A') && (c <= 'Z')) || ((c >= '0') && (c <= '9'))); } int is_frame_id(char * buf) { return (is_frame_char(buf[0]) && is_frame_char(buf[1]) && is_frame_char(buf[2]) && is_frame_char(buf[3])); } int meta_parse_id3v2_frame(metadata_t * meta, unsigned char * buf, int len, int version, int unsynch_all) { char frame_id[5]; int frame_size = 0; int pay_len = 0; /* detect padding/footer, consume rest of payload */ if ((buf[0] == '\0') || ((buf[0] == '3') && (buf[1] == 'D') && (buf[2] == 'I'))) { return len; } if (len < 10) { return len; } memcpy(frame_id, buf, 4); frame_id[4] = '\0'; if (!is_frame_id(frame_id)) { fprintf(stderr, "meta_parse_id3v2_frame: Frame ID expected, got 0x%x%x%x%x\n", (unsigned char)frame_id[0], (unsigned char)frame_id[1], (unsigned char)frame_id[2], (unsigned char)frame_id[3]); return len; } if (version == 0x03) { frame_size = pay_len = meta_id3v2_read_int(buf+4); } else if (version == 0x04) { frame_size = pay_len = meta_id3v2_read_synchsafe_int(buf+4); if (unsynch_all || (buf[9] & 0x02)) { /* unsynch-ed frame */ pay_len = un_unsynch(buf+10, frame_size); } } if (frame_id[0] == 'T') { if ((frame_id[1] == 'X') && (frame_id[2] == 'X') && (frame_id[3] == 'X')) { meta_parse_id3v2_txxx(meta, buf, pay_len); } else { meta_parse_id3v2_t___(meta, buf, pay_len); } } else if (frame_id[0] == 'W') { if ((frame_id[1] == 'X') && (frame_id[2] == 'X') && (frame_id[3] == 'X')) { meta_parse_id3v2_wxxx(meta, buf, pay_len); } else { meta_parse_id3v2_w___(meta, buf, pay_len); } } else if (strcmp(frame_id, "COMM") == 0) { meta_parse_id3v2_comm(meta, buf, pay_len); } else if (strcmp(frame_id, "APIC") == 0) { meta_parse_id3v2_apic(meta, buf, pay_len); } else if (strcmp(frame_id, "RVA2") == 0) { meta_parse_id3v2_rva2(meta, buf, pay_len); } else { /* save the data in a hidden frame to preserve it for write-back */ meta_parse_id3v2_hidden(meta, buf, pay_len); } return frame_size+10; } int metadata_from_id3v2(metadata_t * meta, unsigned char * buf, int length) { int pos = 10; int payload_length = 0; if ((buf[3] != 0x3) && (buf[3] != 0x4)) { /* ID3v2 version not 2.3 or 2.4, not supported */ return 0; } /* In ID3v2.3 first unsynch the whole tag (after header), then skip extended header. In ID3v2.4 frames are individually unsynch-ed. */ if (buf[3] == 0x03) { if (buf[5] & 0x80) { payload_length = un_unsynch(buf+pos, length-pos); } else { payload_length = length - pos; } if (buf[5] & 0x40) { int ext_len = meta_id3v2_read_int(buf+10) + 4; pos += ext_len; payload_length -= ext_len; } } else if (buf[3] == 0x04) { payload_length = length - pos; if (buf[5] & 0x40) { int ext_len = meta_id3v2_read_synchsafe_int(buf+10); pos += ext_len; payload_length -= ext_len; } } while (length > pos) { pos += meta_parse_id3v2_frame(meta, buf+pos, payload_length, buf[3], buf[5] & 0x80); } return 1; } void meta_render_append_frame(unsigned char * data, int length, unsigned char ** buf, int * size) { unsigned char * payload; int pay_len; unsynch(data+10, length-10, &payload, &pay_len); *buf = realloc(*buf, *size+10+pay_len); memcpy(*buf+*size, data, 10); (*buf)[*size+8] = 0x0; (*buf)[*size+9] = 0x2; /* set unsynchronization flag */ meta_id3v2_write_synchsafe_int(*buf+*size+4, pay_len); memcpy(*buf+*size+10, payload, pay_len); *size += 10 + pay_len; free(payload); } void meta_render_id3v2_txxx(meta_frame_t * frame, unsigned char ** buf, int * size) { unsigned char * data; int length; char * frame_id; int len1 = strlen(frame->field_name); int len2 = strlen(frame->field_val); length = 12 + len1 + len2; data = (unsigned char *)malloc(length); if (data == NULL) { fprintf(stderr, "meta_render_id3v2_txxx: malloc error\n"); return; } meta_get_fieldname_embedded(META_TAG_ID3v2, frame->type, &frame_id); memcpy(data, frame_id, 4); data[10] = 0x03; /* text encoding: UTF-8 */ memcpy(data+11, frame->field_name, len1); data[11 + len1] = '\0'; memcpy(data + 12 + len1, frame->field_val, len2); meta_render_append_frame(data, length, buf, size); free(data); } void meta_render_id3v2_t___(meta_frame_t * frame, unsigned char ** buf, int * size) { unsigned char * data; int length; char * frame_id; char fval[MAXLEN]; char * field_val = NULL; int field_len = 0; char * renderfmt = meta_get_field_renderfmt(frame->type); if (META_FIELD_TEXT(frame->type)) { field_val = frame->field_val; field_len = strlen(field_val); } else if (META_FIELD_INT(frame->type)) { snprintf(fval, MAXLEN-1, renderfmt, frame->int_val); field_val = fval; field_len = strlen(field_val); } else if (META_FIELD_FLOAT(frame->type)) { snprintf(fval, MAXLEN-1, renderfmt, frame->float_val); field_val = fval; field_len = strlen(field_val); } length = 11+field_len; data = (unsigned char *)malloc(length); if (data == NULL) { fprintf(stderr, "meta_render_id3v2_t___: malloc error\n"); return; } meta_get_fieldname_embedded(META_TAG_ID3v2, frame->type, &frame_id); memcpy(data, frame_id, 4); data[10] = 0x03; /* text encoding: UTF-8 */ memcpy(data+11, field_val, field_len); meta_render_append_frame(data, length, buf, size); free(data); } void meta_render_id3v2_wxxx(meta_frame_t * frame, unsigned char ** buf, int * size) { unsigned char * data; int length; char * frame_id; int len1 = strlen(frame->field_name); int len2 = strlen(frame->field_val); char * link = meta_id3v2_latin1_from_utf8(frame->field_val, len2); if (link == NULL) { fprintf(stderr, "meta_render_id3v2_wxxx: URL not convertible to iso-8859-1.\n"); return; } len2 = strlen(link); length = 12 + len1 + len2; data = (unsigned char *)malloc(length); if (data == NULL) { fprintf(stderr, "meta_render_id3v2_wxxx: malloc error\n"); return; } meta_get_fieldname_embedded(META_TAG_ID3v2, frame->type, &frame_id); memcpy(data, frame_id, 4); data[10] = 0x03; /* text encoding: UTF-8 */ memcpy(data+11, frame->field_name, len1); data[11 + len1] = '\0'; memcpy(data + 12 + len1, link, len2); meta_render_append_frame(data, length, buf, size); free(data); } void meta_render_id3v2_w___(meta_frame_t * frame, unsigned char ** buf, int * size) { unsigned char * data; int length; char * frame_id; int field_len = strlen(frame->field_val); char * link = meta_id3v2_latin1_from_utf8(frame->field_val, field_len); if (link == NULL) { fprintf(stderr, "meta_render_id3v2_w___: URL not convertible to iso-8859-1.\n"); return; } field_len = strlen(link); length = 10+field_len; data = (unsigned char *)malloc(length); if (data == NULL) { fprintf(stderr, "meta_render_id3v2_w___: malloc error\n"); return; } meta_get_fieldname_embedded(META_TAG_ID3v2, frame->type, &frame_id); memcpy(data, frame_id, 4); memcpy(data+10, link, field_len); meta_render_append_frame(data, length, buf, size); free(data); } void meta_render_id3v2_comm(meta_frame_t * frame, unsigned char ** buf, int * size) { unsigned char * data; int length; char * frame_id; length = 15+strlen(frame->field_val); data = (unsigned char *)malloc(length); if (data == NULL) { fprintf(stderr, "meta_render_id3v2_comm: malloc error\n"); return; } meta_get_fieldname_embedded(META_TAG_ID3v2, frame->type, &frame_id); memcpy(data, frame_id, 4); data[10] = 0x03; /* text encoding: UTF-8 */ memset(data+11, 0x0, 4); /* language and short content descr. is empty */ memcpy(data+15, frame->field_val, strlen(frame->field_val)); meta_render_append_frame(data, length, buf, size); free(data); } void meta_render_id3v2_apic(meta_frame_t * frame, unsigned char ** buf, int * size) { unsigned char * data; int length; char * frame_id; int len1 = strlen(frame->field_name); int len2 = strlen(frame->field_val); length = 14 + len1 + len2 + frame->length; data = (unsigned char *)malloc(length); if (data == NULL) { fprintf(stderr, "meta_render_id3v2_apic: malloc error\n"); return; } meta_get_fieldname_embedded(META_TAG_ID3v2, frame->type, &frame_id); memcpy(data, frame_id, 4); data[10] = 0x03; /* text encoding: UTF-8 */ memcpy(data+11, frame->field_name, len1); data[11+len1] = '\0'; data[12+len1] = frame->int_val; /* picture type */ memcpy(data+13+len1, frame->field_val, len2); data[13+len1+len2] = '\0'; memcpy(data+14+len1+len2, frame->data, frame->length); meta_render_append_frame(data, length, buf, size); free(data); } void meta_render_id3v2_rva2(meta_frame_t * frame, unsigned char ** buf, int * size) { unsigned char * data; int length; char * frame_id; int len1; signed int voladj_fixed; if (frame->field_val[0] == '\0') { free(frame->field_val); frame->field_val = strdup("Aqualung"); } len1 = strlen(frame->field_val); length = 15 + len1; data = (unsigned char *)malloc(length); if (data == NULL) { fprintf(stderr, "meta_render_id3v2_apic: malloc error\n"); return; } meta_get_fieldname_embedded(META_TAG_ID3v2, frame->type, &frame_id); memcpy(data, frame_id, 4); memcpy(data+10, frame->field_val, len1); data[10+len1] = '\0'; data[11+len1] = 0x01; /* Master volume */ voladj_fixed = frame->float_val * 512; data[12+len1] = (voladj_fixed & 0xff00) >> 8; data[13+len1] = voladj_fixed & 0xff; data[14+len1] = 0x00; /* no peak volume */ meta_render_append_frame(data, length, buf, size); free(data); } void meta_render_id3v2_hidden(meta_frame_t * frame, unsigned char ** buf, int * size) { unsigned char * data; int length; unsynch(frame->data+10, frame->length-10, &data, &length); *buf = realloc(*buf, *size+10+length); memcpy(*buf+*size, frame->data, 10); (*buf)[*size+9] |= 0x2; /* set unsynchronization flag */ memcpy(*buf+*size+10, data, length); *size += 10 + length; free(data); } void metadata_render_id3v2_frame(meta_frame_t * frame, unsigned char ** buf, int * size) { char * frame_id; if (frame->type == META_FIELD_HIDDEN) { meta_render_id3v2_hidden(frame, buf, size); return; } meta_get_fieldname_embedded(META_TAG_ID3v2, frame->type, &frame_id); if (frame_id[0] == 'T') { if ((frame_id[1] == 'X') && (frame_id[2] == 'X') && (frame_id[3] == 'X')) { meta_render_id3v2_txxx(frame, buf, size); } else { meta_render_id3v2_t___(frame, buf, size); } } else if (frame_id[0] == 'W') { if ((frame_id[1] == 'X') && (frame_id[2] == 'X') && (frame_id[3] == 'X')) { meta_render_id3v2_wxxx(frame, buf, size); } else { meta_render_id3v2_w___(frame, buf, size); } } else if (strcmp(frame_id, "COMM") == 0) { meta_render_id3v2_comm(frame, buf, size); } else if (strcmp(frame_id, "APIC") == 0) { meta_render_id3v2_apic(frame, buf, size); } else if (strcmp(frame_id, "RVA2") == 0) { meta_render_id3v2_rva2(frame, buf, size); } else { meta_render_id3v2_hidden(frame, buf, size); } } /* Render metadata to ID3v2 byte array. * Returns META_ERROR_*. * On success (META_ERROR_NONE) data and length * are set to a pointer of the newly allocated buffer * and the length of the data. */ int metadata_to_id3v2(metadata_t * meta, unsigned char ** data, int * length) { meta_frame_t * frame; unsigned char * buf; int size = 10; buf = (unsigned char *)calloc(1, 10); if (buf == NULL) { return META_ERROR_NOMEM; } buf[0] = 'I'; buf[1] = 'D'; buf[2] = '3'; buf[3] = 0x4; /* ID3v2.4 */ buf[5] = 0x80; /* Unsynchronize all frames */ frame = metadata_get_frame_by_tag(meta, META_TAG_ID3v2, NULL); while (frame != NULL) { metadata_render_id3v2_frame(frame, &buf, &size); frame = metadata_get_frame_by_tag(meta, META_TAG_ID3v2, frame); } meta_id3v2_write_synchsafe_int(buf+6, size); *data = buf; *length = size; return META_ERROR_NONE; } int meta_id3v2_padding_size(int size) { /* pad the size of the tag to be an integer multiple of 2K, added padding is between 2K and 4K. */ return 2048 * ((size / 2048) + 2); } void meta_id3v2_pad(unsigned char ** buf, int * size, int padded_size) { *buf = (unsigned char *)realloc(*buf, padded_size); if (*buf == NULL) { fprintf(stderr, "meta_id3v2_pad: realloc error\n"); return; } memset(*buf+*size, 0x0, padded_size - *size); meta_id3v2_write_synchsafe_int(*buf+6, padded_size-10); *size = padded_size; } /* move backward the whole contents of the file with length bytes, so file will be length bytes shorter (delete from beginning). */ int meta_id3v2_pull_file(char * filename, FILE * file, int length) { u_int32_t pos; u_int32_t len; int bufsize = 1024*1024; unsigned char * buf; int eof = 0; buf = malloc(bufsize); if (buf == NULL) { fprintf(stderr, "meta_id3v2_pull_file: malloc error\n"); fclose(file); return META_ERROR_NOMEM; } pos = length; while (!eof) { fseek(file, pos, SEEK_SET); len = fread(buf, 1, bufsize, file); if (len < bufsize) { if (feof(file)) { eof = 1; } else { fprintf(stderr, "meta_id3v2_pull_file: fread error\n"); free(buf); fclose(file); return META_ERROR_INTERNAL; } } fseek(file, pos - length, SEEK_SET); if (fwrite(buf, 1, len, file) != len) { fprintf(stderr, "meta_id3v2_pull_file: fwrite error\n"); free(buf); fclose(file); return META_ERROR_INTERNAL; } pos += len; } pos -= length; if (truncate(filename, pos) < 0) { fprintf(stderr, "meta_id3v2_pull_file: truncate() failed on %s\n", filename); free(buf); fclose(file); return META_ERROR_INTERNAL; } free(buf); return META_ERROR_NONE; } /* move forward the whole contents of the file with length bytes, so file will be length bytes longer (add to beginning). */ int meta_id3v2_push_file(FILE * file, int length) { u_int32_t pos; u_int32_t len; int bufsize = 1024*1024; unsigned char * buf; fseek(file, 0L, SEEK_END); pos = ftell(file); buf = malloc(bufsize); if (buf == NULL) { fprintf(stderr, "meta_id3v2_push_file: malloc error\n"); fclose(file); return META_ERROR_NOMEM; } while (pos > 0) { if (pos >= bufsize) { len = bufsize; pos -= len; } else { len = pos; pos = 0; } fseek(file, pos, SEEK_SET); if (fread(buf, 1, len, file) != len) { fprintf(stderr, "meta_id3v2_push_file: fread() failed\n"); free(buf); fclose(file); return META_ERROR_INTERNAL; } fseek(file, pos+length, SEEK_SET); if (fwrite(buf, 1, len, file) != len) { fprintf(stderr, "meta_id3v2_push_file: fwrite error\n"); free(buf); fclose(file); return META_ERROR_INTERNAL; } } free(buf); return META_ERROR_NONE; } int meta_id3v2_write_tag(FILE * file, unsigned char * buf, int len) { /* write the tag to the beginning of the file */ fseek(file, 0L, SEEK_SET); if (fwrite(buf, 1, len, file) != len) { fprintf(stderr, "meta_id3v2_write_tag: fwrite error\n"); fclose(file); return META_ERROR_INTERNAL; } return META_ERROR_NONE; } int meta_id3v2_rewrite(char * filename, unsigned char ** buf, int * len) { FILE * file; unsigned char buffer[12]; u_int32_t file_size; u_int32_t id3v2_length; int ret; if ((file = fopen(filename, "r+b")) == NULL) { fprintf(stderr, "meta_id3v2_rewrite: fopen() failed\n"); return META_ERROR_NOT_WRITABLE; } fseek(file, 0L, SEEK_END); file_size = ftell(file); fseek(file, 0L, SEEK_SET); if (file_size < 21) { /* 10 bytes ID3v2 header + 10 bytes frame header + 1 */ /* no ID3v2 tag found, prepend tag with padding */ int padding_size = meta_id3v2_padding_size(*len); meta_id3v2_pad(buf, len, padding_size); ret = meta_id3v2_push_file(file, padding_size); if (ret != META_ERROR_NONE) { return ret; } ret = meta_id3v2_write_tag(file, *buf, *len); fclose(file); return ret; } else { if (fread(buffer, 1, 10, file) != 10) { fprintf(stderr, "meta_id3v2_delete: fread() failed\n"); fclose(file); return META_ERROR_INTERNAL; } if ((buffer[0] != 'I') || (buffer[1] != 'D') || (buffer[2] != '3')) { /* no ID3v2 tag found, prepend tag with padding */ int padding_size = meta_id3v2_padding_size(*len); meta_id3v2_pad(buf, len, padding_size); ret = meta_id3v2_push_file(file, padding_size); if (ret != META_ERROR_NONE) { fclose(file); return ret; } ret = meta_id3v2_write_tag(file, *buf, *len); fclose(file); return ret; } else { id3v2_length = meta_id3v2_read_synchsafe_int(buffer+6); id3v2_length += 10; /* add 10 byte header */ if (id3v2_length < *len) { /* rewrite whole file: remove old tag, write new tag with padding */ int padding_size = meta_id3v2_padding_size(*len); meta_id3v2_pad(buf, len, padding_size); ret = meta_id3v2_push_file(file, padding_size - id3v2_length); if (ret != META_ERROR_NONE) { fclose(file); return ret; } ret = meta_id3v2_write_tag(file, *buf, *len); fclose(file); return ret; } else if (*len + 32*1024 < id3v2_length) { /* if new tag is more than 32K shorter than the old, rewrite file to shrink it. */ int padding_size = meta_id3v2_padding_size(*len); meta_id3v2_pad(buf, len, padding_size); ret = meta_id3v2_pull_file(filename, file, id3v2_length - padding_size); if (ret != META_ERROR_NONE) { return ret; } ret = meta_id3v2_write_tag(file, *buf, *len); fclose(file); return ret; } else { /* write new tag, with remaining space as padding */ meta_id3v2_pad(buf, len, id3v2_length); ret = meta_id3v2_write_tag(file, *buf, *len); fclose(file); return ret; } } } } int meta_id3v2_delete(char * filename) { FILE * file; unsigned char buffer[12]; u_int32_t file_size; u_int32_t id3v2_length; int ret; if ((file = fopen(filename, "r+b")) == NULL) { fprintf(stderr, "meta_id3v2_delete: fopen() failed\n"); return META_ERROR_NOT_WRITABLE; } fseek(file, 0L, SEEK_END); file_size = ftell(file); fseek(file, 0L, SEEK_SET); if (file_size < 21) { /* 10 bytes ID3v2 header + 10 bytes frame header + 1 */ fclose(file); return META_ERROR_NONE; } if (fread(buffer, 1, 10, file) != 10) { fprintf(stderr, "meta_id3v2_delete: fread() failed\n"); fclose(file); return META_ERROR_INTERNAL; } if ((buffer[0] != 'I') || (buffer[1] != 'D') || (buffer[2] != '3')) { /* no ID3v2 tag found -- we're done */ fclose(file); return META_ERROR_NONE; } else { id3v2_length = meta_id3v2_read_synchsafe_int(buffer+6); id3v2_length += 10; /* add 10 byte header */ ret = meta_id3v2_pull_file(filename, file, id3v2_length); if (ret != META_ERROR_NONE) { return ret; } fclose(file); } return META_ERROR_NONE; } aqualung-0.9beta11/src/metadata_ogg.h0000644000175000001440000000440310662105565014475 00000000000000/* -*- linux-c -*- Copyright (C) 2007 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: metadata_ogg.h 786 2007-08-19 18:23:59Z tszilagyi $ */ #ifndef _METADATA_OGG_H #define _METADATA_OGG_H #include #ifdef HAVE_OGG_VORBIS #ifdef _WIN32 #undef _WIN32 #include #define _WIN32 #else #include #endif /* _WIN32 */ #endif /* HAVE_OGG_VORBIS */ #include #include "common.h" #include "metadata.h" #define META_OGG_FRAGM_PACKET 0x01 #define META_OGG_BOS 0x02 #define META_OGG_EOS 0x04 typedef struct { unsigned char version; char flags; u_int64_t granulepos; u_int32_t serialno; u_int32_t seqno; u_int32_t checksum; unsigned char n_segments; unsigned char segment_table[256]; unsigned char * data; } meta_ogg_page_t; GSList * meta_ogg_parse(char * filename); int meta_ogg_render(GSList * slist, char * filename, int n_pages); void meta_ogg_free(GSList * slist); unsigned char * meta_ogg_get_vc_packet(GSList * slist, unsigned int * length, unsigned int * n_pages); unsigned int meta_ogg_get_page_size(GSList * slist, int nth); unsigned int meta_ogg_vc_get_total_growable(GSList * slist); GSList * meta_ogg_vc_encapsulate_payload(GSList * slist, unsigned char ** payload, unsigned int length, int * n_pages_to_write); unsigned char * meta_ogg_vc_render(metadata_t * meta, unsigned int * length); #ifdef HAVE_OGG_VORBIS metadata_t * metadata_from_vorbis_comment(vorbis_comment * vc); #endif /* HAVE_OGG_VORBIS */ #endif /* _METADATA_OGG_H */ aqualung-0.9beta11/src/metadata_ogg.c0000644000175000001440000005452310746711634014503 00000000000000/* -*- linux-c -*- Copyright (C) 2007 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: metadata_ogg.c 987 2008-01-26 20:09:54Z tszilagyi $ */ #include #include #include #include #include #include #include #include "common.h" #include "i18n.h" #include "metadata_ogg.h" static const u_int32_t crc_table[256] = { 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75, 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d, 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072, 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba, 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53, 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b, 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3, 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec, 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4 }; /* CRC for computing Ogg page checksums. * initial value and final XOR = 0, generator polynomial=0x04c11db7. */ u_int32_t meta_ogg_crc(unsigned char * data, int length) { u_int32_t sum = 0; int i; for (i = 0; i < length; ++i) { sum = (sum << 8) ^ crc_table[((sum >> 24) & 0xff) ^ data[i]]; } return sum; } meta_ogg_page_t * meta_ogg_page_new(void) { meta_ogg_page_t * page = NULL; if ((page = calloc(1, sizeof(meta_ogg_page_t))) == NULL) { fprintf(stderr, "metadata_ogg.c: meta_ogg_page_new() failed: calloc error\n"); return NULL; } return page; } void meta_ogg_page_free(meta_ogg_page_t * page) { if (page->data != NULL) { free(page->data); } free(page); } /* void meta_ogg_page_dump(meta_ogg_page_t * page) { int i; printf("\nOgg page\n"); printf(" version=0x%02x flags=0x%02x\n", page->version, page->flags); printf(" granulepos=0x%016llx\n", page->granulepos); printf(" serialno =0x%08x\n", page->serialno); printf(" seqno =0x%08x\n", page->seqno); printf(" checksum =0x%08x\n", page->checksum); printf(" n_segments=%d\n", page->n_segments); for (i = 0; i < page->n_segments; i++) printf(" %02x", page->segment_table[i]); printf("\n"); } */ unsigned char * meta_ogg_render_page(meta_ogg_page_t * page, unsigned int * length) { int i; unsigned int total_length = 27; unsigned int data_length = 0; u_int32_t crc; unsigned char * data; total_length += page->n_segments; for (i = 0; i < page->n_segments; i++) { total_length += page->segment_table[i]; data_length += page->segment_table[i]; } data = (unsigned char *)calloc(1, total_length); if (data == NULL) { fprintf(stderr, "meta_ogg_render_page: calloc error\n"); return NULL; } /* Render Ogg header */ data[0] = 'O'; data[1] = 'g'; data[2] = 'g'; data[3] = 'S'; data[4] = page->version; data[5] = page->flags; meta_write_int64(page->granulepos, data + 6); meta_write_int32(page->serialno, data + 14); meta_write_int32(page->seqno, data + 18); meta_write_int32(0x00000000, data + 22); data[26] = page->n_segments; /* Render segment table */ for (i = 0; i < page->n_segments; i++) { data[27 + i] = page->segment_table[i]; } /* Render packet data */ memcpy(data + 27 + page->n_segments, page->data, data_length); /* Update CRC */ crc = meta_ogg_crc(data, total_length); meta_write_int32(crc, data + 22); if (length != NULL) { *length = total_length; } return data; } /* read the next page from an Ogg file */ meta_ogg_page_t * meta_ogg_read_page(FILE * file) { unsigned char buf[27]; meta_ogg_page_t * page = NULL; unsigned int data_size = 0; int i; if (fread(buf, 1, 27, file) != 27) { if (feof(file)) { return NULL; } fprintf(stderr, "meta_ogg_read_page: error reading file (Ogg header)\n"); } if ((buf[0] != 'O') || (buf[1] != 'g') || (buf[2] != 'g') || (buf[3] != 'S')) { fprintf(stderr, "meta_ogg_read_page: page sync error\n"); return NULL; } page = meta_ogg_page_new(); if (page == NULL) { return NULL; } page->version = buf[4]; page->flags = buf[5]; page->granulepos = meta_read_int64(buf + 6); page->serialno = meta_read_int32(buf + 14); page->seqno = meta_read_int32(buf + 18); page->checksum = meta_read_int32(buf + 22); page->n_segments = buf[26]; for (i = 0; i < page->n_segments; i++) { unsigned char val; if (fread(&val, 1, 1, file) != 1) { if (feof(file)) { fprintf(stderr, "meta_ogg_read_page: premature end of file\n"); } else { fprintf(stderr, "meta_ogg_read_page: error reading file (Segment table)\n"); } meta_ogg_page_free(page); return NULL; } page->segment_table[i] = val; data_size += val; } page->data = (unsigned char *)calloc(1, data_size); if (page->data == NULL) { fprintf(stderr, "meta_ogg_read_page: calloc error\n"); meta_ogg_page_free(page); return NULL; } if (fread(page->data, 1, data_size, file) != data_size) { if (feof(file)) { fprintf(stderr, "meta_ogg_read_page: premature end of file\n"); } else { fprintf(stderr, "meta_ogg_read_page: error reading file (Packet data)\n"); } meta_ogg_page_free(page); return NULL; } return page; } /* parse an Ogg stream into a list of pages */ GSList * meta_ogg_parse(char * filename) { FILE * file; GSList * slist = NULL; meta_ogg_page_t * page; if ((file = fopen(filename, "rb")) == NULL) { fprintf(stderr, "meta_ogg_parse: fopen() failed\n"); return NULL; } while (1) { page = meta_ogg_read_page(file); if (page != NULL) { slist = g_slist_prepend(slist, (gpointer)page); } else { break; } } fclose(file); return g_slist_reverse(slist); } /* render list of pages to an Ogg stream */ int meta_ogg_render(GSList * slist, char * filename, int n_pages) { FILE * file; meta_ogg_page_t * page; unsigned char * data; unsigned int length; u_int64_t total_length = 0L; int page_count = 0; if ((file = fopen(filename, (n_pages == -1) ? "wb" : "r+b")) == NULL) { fprintf(stderr, "meta_ogg_render: fopen() failed\n"); return -1; } while ((slist != NULL) && ((n_pages == -1) || (page_count < n_pages))) { page = (meta_ogg_page_t *)slist->data; data = meta_ogg_render_page(page, &length); if (data != NULL) { if (fwrite(data, 1, length, file) != length) { fprintf(stderr, "meta_ogg_render: fwrite() failed\n"); return -1; } free(data); } else { fprintf(stderr, "meta_ogg_render: rendering page failed\n"); return -1; } slist = g_slist_next(slist); total_length += length; ++page_count; } fclose(file); return 0; } void meta_ogg_free(GSList * slist) { GSList * s = slist; while (slist != NULL) { meta_ogg_page_t * page = (meta_ogg_page_t *)slist->data; meta_ogg_page_free(page); slist = g_slist_next(slist); } g_slist_free(s); } /* returns packet data size without header and segment table overhead */ unsigned int meta_ogg_get_page_size(GSList * slist, int nth) { meta_ogg_page_t * page = (meta_ogg_page_t *)g_slist_nth_data(slist, nth); int i; unsigned int size = 0; for (i = 0; i < page->n_segments; i++) { size += page->segment_table[i]; } return size; } unsigned int meta_ogg_vc_last_page_growable(meta_ogg_page_t * page) { int i; unsigned char last_lace = 255; unsigned int growable = 0; for (i = 0; page->segment_table[i] == 255; i++); last_lace = page->segment_table[i]; growable += 255 * (255 - page->n_segments); /* add new segments */ growable += (254 - last_lace); /* increase last lace of OXC to 254 */ return growable; } /* Total number of bytes the Vorbis comment packet is * growable without the need for inserting new pages. */ unsigned int meta_ogg_vc_get_total_growable(GSList * slist) { unsigned char * vc_packet; unsigned int vc_length; unsigned int n_pages; unsigned int total_growable = 0; meta_ogg_page_t * page; int i; vc_packet = meta_ogg_get_vc_packet(slist, &vc_length, &n_pages); free(vc_packet); for (i = 0; i < n_pages-1; i++) { /* OXC-only pages to max size */ total_growable += 255*255 - meta_ogg_get_page_size(slist, i+1); } /* current last page of OXC is special */ page = (meta_ogg_page_t *)g_slist_nth_data(slist, n_pages); total_growable += meta_ogg_vc_last_page_growable(page); return total_growable; } /* reads packet starting on the first page of slist */ /* n_pages: number of pages the packet spans */ unsigned char * meta_ogg_read_packet(GSList * slist, unsigned int * length, unsigned int * n_pages) { meta_ogg_page_t * page; int n = 1; int packet_length = 0; int fragment_length; /* length of packet fragment on this page */ int stored_length = 0; unsigned char * data = NULL; int i; while (1) { page = (meta_ogg_page_t *)slist->data; fragment_length = 0; for (i = 0; i < page->n_segments; i++) { packet_length += page->segment_table[i]; fragment_length += page->segment_table[i]; if (page->segment_table[i] < 255) { break; } } data = realloc(data, packet_length); if (data == NULL) { fprintf(stderr, "meta_ogg_read_packet: realloc() error\n"); return NULL; } memcpy(data + stored_length, page->data, fragment_length); stored_length += fragment_length; if (i == page->n_segments) { /* continue with next page */ slist = g_slist_next(slist); ++n; } else { break; } } if (length != NULL) { *length = packet_length; } if (n_pages != NULL) { *n_pages = n; } return data; } unsigned char * meta_ogg_get_vc_packet(GSList * slist, unsigned int * length, unsigned int * n_pages) { /* second Ogg page always begins with Vorbis comment packet */ return meta_ogg_read_packet(g_slist_next(slist), length, n_pages); } int page_data_size(meta_ogg_page_t * page) { int size = 0; int j; for (j = 0; j < page->n_segments; j++) { size += page->segment_table[j]; if (page->segment_table[j] < 255) break; } return size; } GSList * meta_ogg_vc_in_place_ovwr(GSList * slist, int n_pages, unsigned char * payload, int * n_pages_to_write) { int i; int data_pos = 0; for (i = 0; i < n_pages; i++) { meta_ogg_page_t * page = (meta_ogg_page_t *)g_slist_nth_data(slist, i+1); int size = page_data_size(page); memcpy(page->data, payload + data_pos, size); data_pos += size; } *n_pages_to_write = n_pages+1; return slist; } GSList * meta_ogg_vc_expander_encaps(GSList * slist, int n_pages, unsigned int new_length, unsigned int old_length, unsigned char * payload, int * n_pages_to_write) { int i; int data_pos = 0; int expansion = new_length - old_length; for (i = 0; i < n_pages; i++) { meta_ogg_page_t * page = (meta_ogg_page_t *)g_slist_nth_data(slist, i+1); int is_last_page = (i == n_pages-1) ? 1 : 0; int total_size = meta_ogg_get_page_size(slist, i+1); int size = page_data_size(page); int growable = is_last_page ? meta_ogg_vc_last_page_growable(page) : (255*255 - total_size); int new_size; int j; if (growable == 0) { /* this page is already full */ continue; } if (!is_last_page) { growable -= growable % 255; } if (growable > expansion) { growable = expansion; } new_size = size + growable; expansion -= growable; /* move data */ page->data = realloc(page->data, total_size + growable); memmove(page->data + new_size, page->data + size, total_size - size); memcpy(page->data, payload + data_pos, new_size); data_pos += new_size; /* update segment_table accordingly */ memmove(page->segment_table + new_size/255+1, page->segment_table + size/255+1, page->n_segments - (size/255+1)); for (j = 0; j < new_size/255; j++) page->segment_table[j] = 255; page->segment_table[j] = new_size % 255; page->n_segments += (new_size/255 - size/255); } *n_pages_to_write = -1; return slist; } GSList * meta_ogg_vc_paginator_encaps(GSList * slist, int n_pages, unsigned char * payload, unsigned int length) { meta_ogg_page_t * page; meta_ogg_page_t * succ_page; int total_size; int size; int i; int data_pos = 0; GSList * tail; succ_page = (meta_ogg_page_t *)g_slist_nth_data(slist, n_pages); total_size = meta_ogg_get_page_size(slist, n_pages); size = page_data_size(succ_page); if (size == total_size) { slist = g_slist_remove(slist, succ_page); meta_ogg_page_free(succ_page); succ_page = (meta_ogg_page_t *)g_slist_nth_data(slist, n_pages+1); } else { succ_page->flags &= ~META_OGG_FRAGM_PACKET; memmove(succ_page->data, succ_page->data + size, total_size - size); succ_page->data = realloc(succ_page->data, total_size - size); /* update segment_table accordingly */ memmove(succ_page->segment_table, succ_page->segment_table + size/255+1, succ_page->n_segments - (size/255+1)); succ_page->n_segments -= size/255+1; } /* remove pages 1..n_pages-1 */ for (i = n_pages-1; i >= 1; i--) { page = (meta_ogg_page_t *)g_slist_nth_data(slist, i); slist = g_slist_remove(slist, page); meta_ogg_page_free(page); } /* insert new pages for OXC packet */ i = 0; while (length > 0) { int j; int ins_len = 255*255; int n_segments; if (length < ins_len) { ins_len = length; } /* new page with ins_len amount of bytes starting from data_pos */ page = meta_ogg_page_new(); if (i > 0) { page->flags |= META_OGG_FRAGM_PACKET; } page->version = succ_page->version; page->granulepos = 0L; page->serialno = succ_page->serialno; page->seqno = i+1; /* There is 1 preceding Ogg page (stream init) */ page->data = calloc(ins_len, 1); if (page->data == NULL) { fprintf(stderr, "meta_ogg_vc_paginator_encaps(): malloc error\n"); return slist; } memcpy(page->data, payload + data_pos, ins_len); n_segments = ins_len/255+1; for (j = 0; j < n_segments-1; j++) { page->segment_table[j] = 255; } page->segment_table[j] = ins_len % 255; if (length > ins_len) { page->n_segments = n_segments - 1; } else { page->n_segments = n_segments; } slist = g_slist_insert(slist, page, i+1); data_pos += ins_len; length -= ins_len; ++i; } /* Renumber remaining Ogg pages */ tail = g_slist_nth(slist, i); while (tail != NULL) { page = (meta_ogg_page_t *)tail->data; page->seqno = i++; tail = g_slist_next(tail); } return slist; } GSList * meta_ogg_vc_encapsulate_payload(GSList * slist, unsigned char ** payload, unsigned int length, int * n_pages_to_write) { unsigned char * vc_packet; unsigned int vc_length; unsigned int n_pages; unsigned int total_growable; vc_packet = meta_ogg_get_vc_packet(slist, &vc_length, &n_pages); free(vc_packet); if (length <= vc_length) { /* In-place overwrite, padding with zeroes */ if (length < vc_length) { *payload = realloc(*payload, vc_length); memset(*payload + length, 0x00, vc_length - length); } return meta_ogg_vc_in_place_ovwr(slist, n_pages, *payload, n_pages_to_write); } total_growable = meta_ogg_vc_get_total_growable(slist); if (length <= vc_length + total_growable) { /* Expand existing pages */ return meta_ogg_vc_expander_encaps(slist, n_pages, length, vc_length, *payload, n_pages_to_write); } *n_pages_to_write = -1; /* re-render the whole file */ return meta_ogg_vc_paginator_encaps(slist, n_pages, *payload, length); } unsigned char * meta_ogg_vc_render(metadata_t * meta, unsigned int * length) { unsigned char * payload; unsigned int len = 16; unsigned int n_comments = 0; int n_comments_pos; meta_frame_t * frame; payload = (unsigned char *)calloc(len, 1); if (payload == NULL) { fprintf(stderr, "meta_ogg_vc_render(): calloc error\n"); return NULL; } payload[0] = 0x03; payload[1] = 'v'; payload[2] = 'o'; payload[3] = 'r'; payload[4] = 'b'; payload[5] = 'i'; payload[6] = 's'; if ((frame = metadata_get_frame_by_tag(meta, META_TAG_OXC, NULL)) == NULL) { /* no Ogg Xiph comment in this metablock */ /* we cannot really remove it, only delete all of its contents. */ len = 16; payload[len-1] = 0x01; /* last framing bit */ *length = len; return payload; } else { /* vendor string */ frame = metadata_get_frame_by_type(meta, META_FIELD_VENDOR, NULL); unsigned int str_len; if (frame == NULL) { fprintf(stderr, "meta_ogg_vc_render(): programmer error: " "no Vendor string in metablock\n"); free(payload); return NULL; } str_len = strlen(frame->field_val); meta_write_int32(str_len, payload + 7); payload = realloc(payload, len + str_len); memcpy(payload + 11, frame->field_val, str_len); len += str_len; payload = realloc(payload, len + 4); n_comments_pos = 11 + str_len; meta_write_int32(0, payload + n_comments_pos); /* n_comments */ len = n_comments_pos + 4; payload[len] = 0x01; } /* all else */ frame = metadata_get_frame_by_tag(meta, META_TAG_OXC, NULL); while (frame != NULL) { char * vc_entry; int vc_len; int field_len; char * field_val; char fval[MAXLEN]; char * str; char * renderfmt = meta_get_field_renderfmt(frame->type); int i; if (frame->type == META_FIELD_VENDOR) { frame = metadata_get_frame_by_tag(meta, META_TAG_OXC, frame); continue; } if (!meta_get_fieldname_embedded(META_TAG_OXC, frame->type, &str)) { str = frame->field_name; } vc_entry = calloc(strlen(str) + 2, 1); strcpy(vc_entry, str); for (i = 0; vc_entry[i] != '\0'; i++) { vc_entry[i] = tolower(vc_entry[i]); } strcat(vc_entry, "="); vc_len = strlen(vc_entry); if (META_FIELD_TEXT(frame->type)) { field_val = frame->field_val; field_len = strlen(frame->field_val); } else if (META_FIELD_INT(frame->type)) { snprintf(fval, MAXLEN-1, renderfmt, frame->int_val); field_val = fval; field_len = strlen(field_val); } else if (META_FIELD_FLOAT(frame->type)) { snprintf(fval, MAXLEN-1, renderfmt, frame->float_val); field_val = fval; field_len = strlen(field_val); } else { fval[0] = '\0'; field_val = fval; field_len = 0; } vc_entry = realloc(vc_entry, vc_len + field_len); memcpy(vc_entry + vc_len, field_val, field_len); vc_len += field_len; payload = realloc(payload, len + 4); meta_write_int32(vc_len, payload + len); len += 4; payload = realloc(payload, len + vc_len); memcpy(payload + len, vc_entry, vc_len); len += vc_len; ++n_comments; free(vc_entry); frame = metadata_get_frame_by_tag(meta, META_TAG_OXC, frame); } meta_write_int32(n_comments, payload + n_comments_pos); if (n_comments > 0) { payload = realloc(payload, len+1); payload[len] = 0x01; ++len; } *length = len; return payload; } #ifdef HAVE_OGG_VORBIS metadata_t * metadata_from_vorbis_comment(vorbis_comment * vc) { int i; metadata_t * meta; if (!vc) { return NULL; } meta = metadata_new(); meta->valid_tags = META_TAG_OXC; for (i = 0; i < vc->comments; i++) { char key[MAXLEN]; char val[MAXLEN]; char * end; char c; int k, n = 0; for (k = 0; ((c = vc->user_comments[i][n]) != '\0') && (c != '=') && (k < MAXLEN-1); k++) { key[k] = (k == 0) ? toupper(c) : tolower(c); ++n; } key[k] = '\0'; ++n; for (k = 0; ((c = vc->user_comments[i][n]) != '\0') && (k < MAXLEN-1); k++) { val[k] = c; ++n; } val[k] = '\0'; if (!g_utf8_validate(val, -1, (const gchar**)&end)) { fprintf(stderr, "metadata_from_vorbis_comment: invalid UTF-8 sequence in field '%s', truncating.\n", key); *end = '\0'; } if (strlen(val) > 0) { metadata_add_frame_from_keyval(meta, META_TAG_OXC, key, val); } } /* Add Vendor string */ metadata_add_frame_from_keyval(meta, META_TAG_OXC, "vendor", (vc->vendor != NULL) ? vc->vendor : ""); return meta; } #endif /* HAVE_OGG_VORBIS */ aqualung-0.9beta11/src/music_browser.h0000644000175000001440000000372110727033063014741 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: music_browser.h 903 2007-12-04 14:24:41Z peterszilagyi $ */ #ifndef _MUSIC_BROWSER_H #define _MUSIC_BROWSER_H #include void create_music_browser(void); void show_music_browser(void); void hide_music_browser(void); void music_store_search(void); int path_get_store_type(GtkTreePath * p); int iter_get_store_type(GtkTreeIter * i); void music_store_iter_addlist_defmode(GtkTreeIter * ms_iter, GtkTreeIter * pl_iter, int new_tab); int music_store_iter_is_track(GtkTreeIter * iter); void music_store_selection_changed(int store_type); void music_browser_set_font(int cond); void music_store_mark_changed(GtkTreeIter * iter); void music_store_mark_saved(GtkTreeIter* iter_store); void music_store_load_all(void); void music_store_save_all(void); struct keybinds { void (*callback)(gpointer); int keyval1; int keyval2; int state; }; enum { MS_COL_NAME = 0, MS_COL_SORT, MS_COL_FONT, MS_COL_ICON, MS_COL_DATA, MS_COL_COUNT }; enum { STORE_TYPE_INVALID, STORE_TYPE_FILE, STORE_TYPE_CDDA, STORE_TYPE_PODCAST, STORE_TYPE_ALL }; typedef union { int type; } store_t; #endif /* _MUSIC_BROWSER_H */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/music_browser.c0000644000175000001440000006600611316415632014742 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: music_browser.c 1091 2009-12-29 11:22:48Z peterszilagyi $ */ #include #include #include #include #include #include #include #include #include "common.h" #include "utils.h" #include "utils_gui.h" #include "core.h" #include "cover.h" #include "file_info.h" #include "decoder/file_decoder.h" #include "gui_main.h" #include "options.h" #include "playlist.h" #include "search.h" #include "i18n.h" #include "music_browser.h" #include "store_cdda.h" #include "store_file.h" #include "store_podcast.h" extern options_t options; extern GtkWidget * musicstore_toggle; extern GtkListStore * ms_pathlist_store; extern PangoFontDescription *fd_browser; extern PangoFontDescription *fd_statusbar; extern char pl_color_inactive[14]; extern GtkTooltips * aqualung_tooltips; GtkWidget * browser_window; int music_store_changed = 0; GtkWidget * music_tree; GtkTreeStore * music_store = NULL; GtkTreeSelection * music_select; GtkWidget * comment_view; GtkWidget * browser_paned; GtkWidget * statusbar_ms; GtkWidget * toolbar_save_button; GtkWidget * toolbar_edit_button; GtkWidget * toolbar_add_button; GtkWidget * toolbar_remove_button; GtkWidget * blank_menu; GtkWidget * blank__add; GtkWidget * blank__search; GtkWidget * blank__save; GdkPixbuf * icon_store; gboolean music_tree_event_cb(GtkWidget * widget, GdkEvent * event, gpointer user_data); void toolbar__collapse_cb(gpointer data); void toolbar__search_cb(gpointer data); gboolean browser_window_close(GtkWidget * widget, GdkEvent * event, gpointer data) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(musicstore_toggle), FALSE); return TRUE; } gint browser_window_key_pressed(GtkWidget * widget, GdkEventKey * event) { switch (event->keyval) { case GDK_q: case GDK_Q: case GDK_Escape: browser_window_close(NULL, NULL, NULL); return TRUE; } return FALSE; } int path_get_store_type(GtkTreePath * p) { GtkTreeIter iter; GtkTreePath * path; store_t * data; path = gtk_tree_path_copy(p); while (gtk_tree_path_get_depth(path) > 1) { gtk_tree_path_up(path); } gtk_tree_model_get_iter(GTK_TREE_MODEL(music_store), &iter, path); gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter, MS_COL_DATA, &data, -1); gtk_tree_path_free(path); return data->type; } int iter_get_store_type(GtkTreeIter * i) { GtkTreePath * path = gtk_tree_model_get_path(GTK_TREE_MODEL(music_store), i); int ret = path_get_store_type(path); gtk_tree_path_free(path); return ret; } int music_store_iter_is_track(GtkTreeIter * iter) { switch (iter_get_store_type(iter)) { case STORE_TYPE_FILE: return store_file_iter_is_track(iter); #ifdef HAVE_CDDA case STORE_TYPE_CDDA: return store_cdda_iter_is_track(iter); #endif /* HAVE_CDDA */ #ifdef HAVE_PODCAST case STORE_TYPE_PODCAST: return store_podcast_iter_is_track(iter); #endif /* HAVE_PODCAST */ } return 0; } void music_store_iter_addlist_defmode(GtkTreeIter * ms_iter, GtkTreeIter * pl_iter, int new_tab) { switch (iter_get_store_type(ms_iter)) { case STORE_TYPE_FILE: store_file_iter_addlist_defmode(ms_iter, pl_iter, new_tab); break; #ifdef HAVE_CDDA case STORE_TYPE_CDDA: store_cdda_iter_addlist_defmode(ms_iter, pl_iter, new_tab); break; #endif /* HAVE_CDDA */ #ifdef HAVE_PODCAST case STORE_TYPE_PODCAST: store_podcast_iter_addlist_defmode(ms_iter, pl_iter, new_tab); break; #endif /* HAVE_PODCAST */ } } gboolean music_tree_event_cb(GtkWidget * widget, GdkEvent * event, gpointer user_data) { GtkTreeIter iter; GtkTreeModel * model; if (event->type != GDK_KEY_PRESS && event->type != GDK_KEY_RELEASE && event->type != GDK_BUTTON_PRESS && event->type != GDK_2BUTTON_PRESS) { return FALSE; } /* global handlers */ if (event->type == GDK_2BUTTON_PRESS) { if (gtk_tree_selection_get_selected(music_select, NULL, &iter)) { music_store_iter_addlist_defmode(&iter, NULL, 0/*new_tab*/); } return TRUE; } if (event->type == GDK_KEY_PRESS) { GdkEventKey * kevent = (GdkEventKey *)event; switch (kevent->keyval) { case GDK_KP_Enter: case GDK_Return: if (gtk_tree_selection_get_selected(music_select, &model, &iter)) { GtkTreePath * path = gtk_tree_model_get_path(model, &iter); if (gtk_tree_view_row_expanded(GTK_TREE_VIEW(music_tree), path)) { gtk_tree_view_collapse_row(GTK_TREE_VIEW(music_tree), path); } else { gtk_tree_view_expand_row(GTK_TREE_VIEW(music_tree), path, FALSE); } gtk_tree_path_free(path); } return TRUE; case GDK_w: case GDK_W: toolbar__collapse_cb(NULL); return TRUE; case GDK_f: case GDK_F: toolbar__search_cb(NULL); return TRUE; } } if (event->type == GDK_BUTTON_PRESS) { GtkTreePath * path = NULL; GdkEventButton * bevent = (GdkEventButton *)event; if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(music_tree), bevent->x, bevent->y, &path, NULL, NULL, NULL)) { gtk_tree_selection_select_path(music_select, path); gtk_tree_view_set_cursor(GTK_TREE_VIEW(music_tree), path, NULL, FALSE); gtk_tree_path_free(path); if (gtk_tree_selection_get_selected(music_select, NULL, &iter)) { if (bevent->button == 2) { music_store_iter_addlist_defmode(&iter, NULL, 1/*new_tab*/); return TRUE; } } } else { if (bevent->button == 3) { gtk_menu_popup(GTK_MENU(blank_menu), NULL, NULL, NULL, NULL, bevent->button, bevent->time); } return TRUE; } } /* pass event to the selected store */ if (gtk_tree_selection_get_selected(music_select, &model, &iter)) { GtkTreePath * path = gtk_tree_model_get_path(model, &iter); switch (iter_get_store_type(&iter)) { case STORE_TYPE_FILE: store_file_event_cb(event, &iter, path); break; #ifdef HAVE_CDDA case STORE_TYPE_CDDA: store_cdda_event_cb(event, &iter, path); break; #endif /* HAVE_CDDA */ #ifdef HAVE_PODCAST case STORE_TYPE_PODCAST: store_podcast_event_cb(event, &iter, path); break; #endif /* HAVE_PODCAST */ } gtk_tree_path_free(path); } return FALSE; } /****************************************/ void music_store_search(void) { search_dialog(); } void toolbar__search_cb(gpointer data) { music_store_search(); } void toolbar__collapse_cb(gpointer data) { GtkTreeIter iter; GtkTreePath * path; gtk_tree_view_collapse_all(GTK_TREE_VIEW(music_tree)); gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &iter, NULL, 0); path = gtk_tree_model_get_path (GTK_TREE_MODEL(music_store), &iter); if (path) { gtk_tree_view_set_cursor (GTK_TREE_VIEW (music_tree), path, NULL, TRUE); gtk_tree_path_free(path); } } void toolbar__edit_cb(gpointer data) { GtkTreeIter iter; if (gtk_tree_selection_get_selected(music_select, NULL, &iter)) { switch (iter_get_store_type(&iter)) { case STORE_TYPE_FILE: store_file_toolbar__edit_cb(data); break; #ifdef HAVE_PODCAST case STORE_TYPE_PODCAST: store_podcast_toolbar__edit_cb(data); break; #endif /* HAVE_PODCAST */ } } } void toolbar__add_cb(gpointer data) { GtkTreeIter iter; if (gtk_tree_selection_get_selected(music_select, NULL, &iter)) { switch (iter_get_store_type(&iter)) { case STORE_TYPE_FILE: store_file_toolbar__add_cb(data); break; #ifdef HAVE_PODCAST case STORE_TYPE_PODCAST: store_podcast_toolbar__add_cb(data); break; #endif /* HAVE_PODCAST */ } } } void toolbar__remove_cb(gpointer data) { GtkTreeIter iter; if (gtk_tree_selection_get_selected(music_select, NULL, &iter)) { switch (iter_get_store_type(&iter)) { case STORE_TYPE_FILE: store_file_toolbar__remove_cb(data); break; #ifdef HAVE_PODCAST case STORE_TYPE_PODCAST: store_podcast_toolbar__remove_cb(data); break; #endif /* HAVE_PODCAST */ } } } void toolbar__save_cb(gpointer data) { music_store_save_all(); } void music_store_selection_changed(int store_type) { GtkTreeIter iter; if (gtk_tree_selection_get_selected(music_select, NULL, &iter) && (store_type == STORE_TYPE_ALL || iter_get_store_type(&iter) == store_type)) { gtk_tree_selection_unselect_iter(music_select, &iter); gtk_tree_selection_select_iter(music_select, &iter); } } void tree_selection_changed_cb(GtkTreeSelection * selection, gpointer data) { GtkTreeIter iter; GtkTreeModel * model; GtkTextBuffer * buffer; GtkTextIter a_iter, b_iter; buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(comment_view)); gtk_text_buffer_get_bounds(buffer, &a_iter, &b_iter); gtk_text_buffer_delete(buffer, &a_iter, &b_iter); gtk_label_set_text(GTK_LABEL(statusbar_ms), ""); if (gtk_tree_selection_get_selected(selection, &model, &iter)) { switch (iter_get_store_type(&iter)) { case STORE_TYPE_FILE: if (options.enable_mstore_toolbar) { store_file_set_toolbar_sensitivity(&iter, toolbar_edit_button, toolbar_add_button, toolbar_remove_button); } store_file_selection_changed(&iter, buffer, GTK_LABEL(statusbar_ms)); break; #ifdef HAVE_CDDA case STORE_TYPE_CDDA: if (options.enable_mstore_toolbar) { gtk_widget_set_sensitive(toolbar_edit_button, FALSE); gtk_widget_set_sensitive(toolbar_add_button, FALSE); gtk_widget_set_sensitive(toolbar_remove_button, FALSE); } store_cdda_selection_changed(&iter, buffer, GTK_LABEL(statusbar_ms)); break; #endif /* HAVE_CDDA */ #ifdef HAVE_PODCAST case STORE_TYPE_PODCAST: if (options.enable_mstore_toolbar) { store_podcast_set_toolbar_sensitivity(&iter, toolbar_edit_button, toolbar_add_button, toolbar_remove_button); } store_podcast_selection_changed(&iter, buffer, GTK_LABEL(statusbar_ms)); break; #endif /* HAVE_PODCAST */ } } } void browser_drag_data_get(GtkWidget * widget, GdkDragContext * drag_context, GtkSelectionData * data, guint info, guint time, gpointer user_data) { gtk_selection_data_set(data, data->target, 8, (const guchar *) "store\0", 6); } void browser_drag_end(GtkWidget * widget, GdkDragContext * drag_context, gpointer data) { playlist_drag_end(widget, drag_context, data); } void music_tree_expand_stores(void) { GtkTreeIter iter_store; GtkTreePath * path = NULL; int i = 0; if (!options.autoexpand_stores) return; i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &iter_store, NULL, i++)) { path = gtk_tree_model_get_path(GTK_TREE_MODEL(music_store), &iter_store); gtk_tree_view_expand_row(GTK_TREE_VIEW(music_tree), path, FALSE); gtk_tree_path_free(path); } } void music_browser_set_font(int cond) { if (cond) { gtk_widget_modify_font(music_tree, fd_browser); gtk_widget_modify_font(statusbar_ms, fd_statusbar); } } void create_music_browser(void) { GtkWidget * vbox; GtkWidget * hbox; GtkWidget * viewport1; GtkWidget * viewport2; GtkWidget * scrolled_win1; GtkWidget * scrolled_win2; GtkWidget * statusbar_viewport; GtkWidget * statusbar_scrolledwin; GtkWidget * statusbar_hbox; GtkWidget * toolbar_search_button; GtkWidget * toolbar_collapse_all_button; GtkCellRenderer * renderer; GtkTreeViewColumn * column; GtkTextBuffer * buffer; GdkPixbuf * pixbuf; char path[MAXLEN]; GtkTargetEntry target_table[] = { { "aqualung-browser-list", GTK_TARGET_SAME_APP, 1 } }; /* window creating stuff */ browser_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(browser_window), _("Music Store")); g_signal_connect(G_OBJECT(browser_window), "delete_event", G_CALLBACK(browser_window_close), NULL); g_signal_connect(G_OBJECT(browser_window), "key_press_event", G_CALLBACK(browser_window_key_pressed), NULL); gtk_container_set_border_width(GTK_CONTAINER(browser_window), 2); gtk_widget_set_size_request(browser_window, 200, 300); vbox = gtk_vbox_new(FALSE, 0); gtk_container_add(GTK_CONTAINER(browser_window), vbox); if (options.enable_mstore_toolbar) { hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 3); toolbar_search_button = gui_stock_label_button((gchar *)-1, GTK_STOCK_FIND); GTK_WIDGET_UNSET_FLAGS(toolbar_search_button, GTK_CAN_FOCUS); g_signal_connect(G_OBJECT(toolbar_search_button), "clicked", G_CALLBACK(toolbar__search_cb), NULL); gtk_box_pack_start(GTK_BOX(hbox), toolbar_search_button, FALSE, TRUE, 3); aqualung_widget_set_tooltip_text(toolbar_search_button, _("Search...")); toolbar_collapse_all_button = gui_stock_label_button((gchar *)-1, GTK_STOCK_REFRESH); GTK_WIDGET_UNSET_FLAGS(toolbar_collapse_all_button, GTK_CAN_FOCUS); gtk_box_pack_start(GTK_BOX(hbox), toolbar_collapse_all_button, FALSE, TRUE, 3); g_signal_connect(G_OBJECT(toolbar_collapse_all_button), "pressed", G_CALLBACK(toolbar__collapse_cb), NULL); aqualung_widget_set_tooltip_text(toolbar_collapse_all_button, _("Collapse all items")); toolbar_edit_button = gui_stock_label_button((gchar *)-1, GTK_STOCK_EDIT); GTK_WIDGET_UNSET_FLAGS(toolbar_edit_button, GTK_CAN_FOCUS); gtk_box_pack_start(GTK_BOX(hbox), toolbar_edit_button, FALSE, TRUE, 3); g_signal_connect(G_OBJECT(toolbar_edit_button), "pressed", G_CALLBACK(toolbar__edit_cb), NULL); aqualung_widget_set_tooltip_text(toolbar_edit_button, _("Edit item...")); toolbar_add_button = gui_stock_label_button((gchar *)-1, GTK_STOCK_ADD); GTK_WIDGET_UNSET_FLAGS(toolbar_add_button, GTK_CAN_FOCUS); gtk_box_pack_start(GTK_BOX(hbox), toolbar_add_button, FALSE, TRUE, 3); g_signal_connect(G_OBJECT(toolbar_add_button), "pressed", G_CALLBACK(toolbar__add_cb), NULL); aqualung_widget_set_tooltip_text(toolbar_add_button, _("Add item...")); toolbar_remove_button = gui_stock_label_button((gchar *)-1, GTK_STOCK_REMOVE); GTK_WIDGET_UNSET_FLAGS(toolbar_remove_button, GTK_CAN_FOCUS); gtk_box_pack_start(GTK_BOX(hbox), toolbar_remove_button, FALSE, TRUE, 3); g_signal_connect(G_OBJECT(toolbar_remove_button), "pressed", G_CALLBACK(toolbar__remove_cb), NULL); aqualung_widget_set_tooltip_text(toolbar_remove_button, _("Remove item...")); toolbar_save_button = gui_stock_label_button((gchar *)-1, GTK_STOCK_SAVE); GTK_WIDGET_UNSET_FLAGS(toolbar_save_button, GTK_CAN_FOCUS); gtk_box_pack_start(GTK_BOX(hbox), toolbar_save_button, FALSE, TRUE, 3); g_signal_connect(G_OBJECT(toolbar_save_button), "pressed", G_CALLBACK(toolbar__save_cb), NULL); gtk_widget_set_sensitive(toolbar_save_button, FALSE); aqualung_widget_set_tooltip_text(toolbar_save_button, _("Save all stores")); } if (!options.hide_comment_pane) { browser_paned = gtk_vpaned_new(); gtk_box_pack_start(GTK_BOX(vbox), browser_paned, TRUE, TRUE, 0); } /* load tree icons */ if (options.enable_ms_tree_icons) { sprintf(path, "%s/%s", AQUALUNG_DATADIR, "ms-store.png"); icon_store = gdk_pixbuf_new_from_file (path, NULL); store_file_load_icons(); #ifdef HAVE_CDDA store_cdda_load_icons(); #endif /* HAVE_CDDA */ #ifdef HAVE_PODCAST store_podcast_load_icons(); #endif /* HAVE_PODCAST */ } /* create music store tree */ if (!music_store) { music_store = gtk_tree_store_new(MS_COL_COUNT, G_TYPE_STRING, /* visible name */ G_TYPE_STRING, /* string to sort by */ G_TYPE_INT, /* font weight */ GDK_TYPE_PIXBUF, /* icon */ G_TYPE_POINTER); /* data */ } music_tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL(music_store)); gtk_widget_set_name(music_tree, "music_tree"); gtk_tree_view_set_enable_search(GTK_TREE_VIEW(music_tree), FALSE); g_signal_connect(G_OBJECT(music_tree), "event", G_CALLBACK(music_tree_event_cb), NULL); if (options.enable_ms_rules_hint) { gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(music_tree), TRUE); } column = gtk_tree_view_column_new(); gtk_tree_view_column_set_title(column, "name"); renderer = gtk_cell_renderer_pixbuf_new(); gtk_tree_view_column_pack_start(column, renderer, FALSE); gtk_tree_view_column_add_attribute(column, renderer, "pixbuf", MS_COL_ICON); renderer = gtk_cell_renderer_text_new(); gtk_tree_view_column_pack_start(column, renderer, TRUE); gtk_tree_view_column_add_attribute(column, renderer, "text", MS_COL_NAME); gtk_tree_view_column_add_attribute(column, renderer, "weight", MS_COL_FONT); g_object_set(G_OBJECT(renderer), "ellipsize", PANGO_ELLIPSIZE_END, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(music_tree), column); gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(music_tree), FALSE); viewport1 = gtk_viewport_new(NULL, NULL); if (!options.hide_comment_pane) { gtk_paned_pack1(GTK_PANED(browser_paned), viewport1, TRUE, TRUE); } else { gtk_box_pack_start(GTK_BOX(vbox), viewport1, TRUE, TRUE, 0); } scrolled_win1 = gtk_scrolled_window_new(NULL, NULL); gtk_widget_set_size_request(scrolled_win1, -1, 1); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_win1), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_container_add(GTK_CONTAINER(viewport1), scrolled_win1); gtk_container_add(GTK_CONTAINER(scrolled_win1), music_tree); music_select = gtk_tree_view_get_selection(GTK_TREE_VIEW(music_tree)); gtk_tree_selection_set_mode(music_select, GTK_SELECTION_SINGLE); g_signal_connect(G_OBJECT(music_select), "changed", G_CALLBACK(tree_selection_changed_cb), NULL); gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(music_store), MS_COL_SORT, GTK_SORT_ASCENDING); music_tree_expand_stores(); /* setup drag and drop */ gtk_drag_source_set(music_tree, GDK_BUTTON1_MASK, target_table, sizeof(target_table) / sizeof(GtkTargetEntry), GDK_ACTION_COPY); snprintf(path, MAXLEN-1, "%s/drag.png", AQUALUNG_DATADIR); if ((pixbuf = gdk_pixbuf_new_from_file(path, NULL)) != NULL) { gtk_drag_source_set_icon_pixbuf(music_tree, pixbuf); } g_signal_connect(G_OBJECT(music_tree), "drag_data_get", G_CALLBACK(browser_drag_data_get), NULL); g_signal_connect(G_OBJECT(music_tree), "drag_end", G_CALLBACK(browser_drag_end), NULL); /* create popup menu for blank space */ blank_menu = gtk_menu_new(); register_toplevel_window(blank_menu, TOP_WIN_SKIN); blank__add = gtk_menu_item_new_with_label(_("Create empty store...")); blank__search = gtk_menu_item_new_with_label(_("Search...")); blank__save = gtk_menu_item_new_with_label(_("Save all stores")); gtk_menu_shell_append(GTK_MENU_SHELL(blank_menu), blank__add); gtk_menu_shell_append(GTK_MENU_SHELL(blank_menu), blank__search); gtk_menu_shell_append(GTK_MENU_SHELL(blank_menu), blank__save); g_signal_connect_swapped(G_OBJECT(blank__add), "activate", G_CALLBACK(store__add_cb), NULL); g_signal_connect_swapped(G_OBJECT(blank__search), "activate", G_CALLBACK(toolbar__search_cb), NULL); g_signal_connect_swapped(G_OBJECT(blank__save), "activate", G_CALLBACK(toolbar__save_cb), NULL); gtk_widget_show(blank__add); gtk_widget_show(blank__search); gtk_widget_show(blank__save); store_file_create_popup_menu(); #ifdef HAVE_CDDA store_cdda_create_popup_menu(); #endif /* HAVE_CDDA */ #ifdef HAVE_PODCAST store_podcast_create_popup_menu(); #endif /* HAVE_PODCAST */ /* create text widget for comments */ comment_view = gtk_text_view_new(); gtk_widget_set_name(comment_view, "comment_view"); gtk_text_view_set_editable(GTK_TEXT_VIEW(comment_view), FALSE); gtk_text_view_set_pixels_above_lines(GTK_TEXT_VIEW(comment_view), 3); gtk_text_view_set_left_margin(GTK_TEXT_VIEW(comment_view), 3); gtk_text_view_set_right_margin(GTK_TEXT_VIEW(comment_view), 3); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(comment_view), GTK_WRAP_WORD); buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(comment_view)); scrolled_win2 = gtk_scrolled_window_new(NULL, NULL); gtk_widget_set_size_request(scrolled_win2, -1, 1); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_win2), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); viewport2 = gtk_viewport_new(NULL, NULL); if (!options.hide_comment_pane) { gtk_paned_pack2(GTK_PANED(browser_paned), viewport2, FALSE, TRUE); } gtk_container_add(GTK_CONTAINER(viewport2), scrolled_win2); gtk_container_add(GTK_CONTAINER(scrolled_win2), comment_view); if (!options.hide_comment_pane) { gtk_paned_set_position(GTK_PANED(browser_paned), options.browser_paned_pos); } store_file_insert_progress_bar(vbox); if (options.enable_mstore_statusbar) { statusbar_scrolledwin = gtk_scrolled_window_new(NULL, NULL); gtk_widget_set_size_request(statusbar_scrolledwin, 1, -1); /* MAGIC */ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(statusbar_scrolledwin), GTK_POLICY_NEVER, GTK_POLICY_NEVER); statusbar_viewport = gtk_viewport_new(NULL, NULL); gtk_widget_set_name(statusbar_viewport, "info_viewport"); gtk_container_add(GTK_CONTAINER(statusbar_scrolledwin), statusbar_viewport); gtk_box_pack_start(GTK_BOX(vbox), statusbar_scrolledwin, FALSE, TRUE, 2); gtk_widget_set_events(statusbar_viewport, GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK); g_signal_connect(G_OBJECT(statusbar_viewport), "button_press_event", G_CALLBACK(scroll_btn_pressed), NULL); g_signal_connect(G_OBJECT(statusbar_viewport), "button_release_event", G_CALLBACK(scroll_btn_released), (gpointer)statusbar_scrolledwin); g_signal_connect(G_OBJECT(statusbar_viewport), "motion_notify_event", G_CALLBACK(scroll_motion_notify), (gpointer)statusbar_scrolledwin); statusbar_hbox = gtk_hbox_new(FALSE, 0); gtk_container_set_border_width(GTK_CONTAINER(statusbar_hbox), 1); gtk_container_add(GTK_CONTAINER(statusbar_viewport), statusbar_hbox); statusbar_ms = gtk_label_new(""); gtk_widget_set_name(statusbar_ms, "label_info"); gtk_box_pack_end(GTK_BOX(statusbar_hbox), statusbar_ms, FALSE, FALSE, 0); } music_browser_set_font(options.override_skin_settings); } void show_music_browser(void) { options.browser_on = 1; gtk_window_move(GTK_WINDOW(browser_window), options.browser_pos_x, options.browser_pos_y); gtk_window_resize(GTK_WINDOW(browser_window), options.browser_size_x, options.browser_size_y); gtk_widget_show_all(browser_window); register_toplevel_window(browser_window, TOP_WIN_SKIN | TOP_WIN_TRAY); if (!options.hide_comment_pane) { gtk_paned_set_position(GTK_PANED(browser_paned), options.browser_paned_pos); } } void hide_music_browser(void) { options.browser_on = 0; gtk_window_get_position(GTK_WINDOW(browser_window), &options.browser_pos_x, &options.browser_pos_y); gtk_window_get_size(GTK_WINDOW(browser_window), &options.browser_size_x, &options.browser_size_y); if (!options.hide_comment_pane) { options.browser_paned_pos = gtk_paned_get_position(GTK_PANED(browser_paned)); } gtk_widget_hide(browser_window); register_toplevel_window(browser_window, TOP_WIN_SKIN); } void music_store_mark_changed(GtkTreeIter * iter) { GtkTreeIter iter_store; GtkTreePath * path; char name[MAXLEN]; char * pname; store_t * data; music_store_selection_changed(STORE_TYPE_FILE); path = gtk_tree_model_get_path(GTK_TREE_MODEL(music_store), iter); while (gtk_tree_path_get_depth(path) > 1) { gtk_tree_path_up(path); } gtk_tree_model_get_iter(GTK_TREE_MODEL(music_store), &iter_store, path); gtk_tree_path_free(path); gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter_store, MS_COL_DATA, &data, -1); switch (data->type) { case STORE_TYPE_FILE: { store_data_t * store_data = (store_data_t *)data; if (store_data->dirty) { return; } store_data->dirty = 1; } break; default: /* skip */ return; } gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter_store, MS_COL_NAME, &pname, -1); name[0] = '*'; name[1] = '\0'; strncat(name, pname, MAXLEN-2); g_free(pname); gtk_tree_store_set(music_store, &iter_store, MS_COL_NAME, name, -1); music_store_changed = 1; gtk_window_set_title(GTK_WINDOW(browser_window), _("*Music Store")); if (options.enable_mstore_toolbar) { gtk_widget_set_sensitive(toolbar_save_button, TRUE); } } void music_store_mark_saved(GtkTreeIter * iter_store) { GtkTreeIter iter; int i; char * pname; store_t * data; gtk_tree_model_get(GTK_TREE_MODEL(music_store), iter_store, MS_COL_DATA, &data, -1); switch (data->type) { case STORE_TYPE_FILE: { store_data_t * store_data = (store_data_t *)data; if (!store_data->dirty) { return; } store_data->dirty = 0; } break; default: /* skip */ return; } gtk_tree_model_get(GTK_TREE_MODEL(music_store), iter_store, MS_COL_NAME, &pname, -1); gtk_tree_store_set(music_store, iter_store, MS_COL_NAME, pname + 1, -1); g_free(pname); i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &iter, NULL, i++)) { gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter, MS_COL_DATA, &data, -1); switch (data->type) { case STORE_TYPE_FILE: { store_data_t * store_data = (store_data_t *)data; if (store_data->dirty) { return; } } break; default: /* skip */ break; } } music_store_changed = 0; gtk_window_set_title(GTK_WINDOW(browser_window), _("Music Store")); if (options.enable_mstore_toolbar) { gtk_widget_set_sensitive(toolbar_save_button, FALSE); } music_store_selection_changed(STORE_TYPE_FILE); } int music_store_get_type(char * filename) { /* dummy implementation */ return STORE_TYPE_FILE; } void music_store_load_all(void) { GtkTreeIter iter_store; char * store_file; char sort[16]; int i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(ms_pathlist_store), &iter_store, NULL, i++)) { gtk_tree_model_get(GTK_TREE_MODEL(ms_pathlist_store), &iter_store, 0, &store_file, -1); switch (music_store_get_type(store_file)) { case STORE_TYPE_FILE: snprintf(sort, 15, "%03d", i+1); store_file_load(store_file, sort); break; } g_free(store_file); } music_tree_expand_stores(); } void music_store_save_all(void) { GtkTreeIter iter_store; int i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &iter_store, NULL, i++)) { switch (iter_get_store_type(&iter_store)) { case STORE_TYPE_FILE: store_file_save(&iter_store); break; } } } // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/options.h0000644000175000001440000001464311324131225013547 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: options.h 1092 2010-01-03 15:58:59Z peterszilagyi $ */ #ifndef _OPTIONS_H #define _OPTIONS_H #include "common.h" typedef struct { int button_nr; int command; } mouse_button_command_t; typedef struct { /* home directory */ char home[MAXLEN]; /* normally $HOME/.aqualung */ char confdir[MAXLEN]; /* current working directory when program is started */ char cwd[MAXLEN]; /* to keep track of file selector dialogs; start with $HOME */ char audiodir[MAXLEN]; char currdir[MAXLEN]; char exportdir[MAXLEN]; char plistdir[MAXLEN]; char podcastdir[MAXLEN]; char ripdir[MAXLEN]; char storedir[MAXLEN]; /* directory of skin in use */ char skin[MAXLEN]; /* Misc - not accessible from the Settings dialog */ float vol; float bal; int time_idx[3]; int main_pos_x; int main_pos_y; int main_size_x; int main_size_y; int browser_pos_x; int browser_pos_y; int browser_size_x; int browser_size_y; int browser_on; int browser_paned_pos; int playlist_pos_x; int playlist_pos_y; int playlist_size_x; int playlist_size_y; int playlist_on; int repeat_on; int repeat_all_on; int shuffle_on; int search_pl_flags; int search_ms_flags; int ifpmanager_size_x; int ifpmanager_size_y; float loop_range_start; float loop_range_end; int wm_systray_warn; int podcasts_autocheck; int cdrip_deststore; int cdrip_file_format; int cdrip_bitrate; int cdrip_vbr; int cdrip_metadata; char export_template[MAXLEN]; int export_subdir_artist; int export_subdir_album; int export_subdir_limit; int export_file_format; int export_bitrate; int export_vbr; int export_metadata; int export_filter_same; int export_excl_enabled; char export_excl_pattern[MAXLEN]; int batch_tag_flags; /* General */ char title_format[MAXLEN]; char default_param[MAXLEN]; int enable_tooltips; int disable_buttons_relief; int combine_play_pause; int combine_play_pause_shadow; int simple_view_in_fx; int simple_view_in_fx_shadow; int show_sn_title; int united_minimization; int show_hidden; int main_window_always_on_top; int tags_tab_first; int dont_show_cover; int show_cover_for_ms_tracks_only; int use_systray; int systray_start_minimized; int systray_mouse_wheel_horizontal; int systray_mouse_wheel_vertical; int systray_mouse_buttons_count; mouse_button_command_t * systray_mouse_buttons; /* Playlist */ int playlist_is_embedded; int playlist_is_embedded_shadow; int buttons_at_the_bottom; int buttons_at_the_bottom_shadow; int playlist_always_show_tabs; int playlist_show_close_button_in_tab; int playlist_is_tree; int album_shuffle_mode; int auto_save_playlist; int playlist_auto_save; int playlist_auto_save_int; int enable_playlist_statusbar; int enable_playlist_statusbar_shadow; int pl_statusbar_show_size; int show_rva_in_playlist; int show_length_in_playlist; int show_active_track_name_in_bold; int auto_roll_to_active_track; int enable_pl_rules_hint; int plcol_idx[3]; /* Music Store */ int hide_comment_pane; int hide_comment_pane_shadow; int enable_mstore_statusbar; int enable_mstore_statusbar_shadow; int ms_statusbar_show_size; int enable_mstore_toolbar; int enable_mstore_toolbar_shadow; int autoexpand_stores; int enable_ms_rules_hint; int enable_ms_tree_icons; int enable_ms_tree_icons_shadow; int ms_confirm_removal; int cover_width; int magnify_smaller_images; /* DSP */ int ladspa_is_postfader; int src_type; /* RVA */ int rva_is_enabled; int rva_env; float rva_refvol; float rva_steepness; int rva_use_averaging; int rva_use_linear_thresh; float rva_avg_linear_thresh; float rva_avg_stddev_thresh; float rva_no_rva_voladj; /* Metadata */ int replaygain_tag_to_use; int batch_mpeg_add_id3v1; int batch_mpeg_add_id3v2; int batch_mpeg_add_ape; int metaedit_auto_clone; int meta_use_basename_only; int meta_rm_extension; int meta_us_to_space; /* CD audio */ int cdda_drive_speed; int cdda_paranoia_mode; int cdda_paranoia_maxretries; int cdda_force_drive_rescan; int cdda_add_to_playlist; int cdda_remove_from_playlist; /* CDDB */ char cddb_server[MAXLEN]; int cddb_timeout; char cddb_email[MAXLEN]; char cddb_local[MAXLEN]; int cddb_cache_only; int cddb_use_http; /* Internet */ int inet_use_proxy; char inet_proxy[MAXLEN]; int inet_proxy_port; char inet_noproxy_domains[MAXLEN]; int inet_timeout; /* Appearance */ int disable_skin_support_settings; int override_skin_settings; char playlist_font[MAX_FONTNAME_LEN]; char browser_font[MAX_FONTNAME_LEN]; char bigtimer_font[MAX_FONTNAME_LEN]; char smalltimer_font[MAX_FONTNAME_LEN]; char songtitle_font[MAX_FONTNAME_LEN]; char songinfo_font[MAX_FONTNAME_LEN]; char statusbar_font[MAX_FONTNAME_LEN]; char song_color[MAX_COLORNAME_LEN]; char activesong_color[MAX_COLORNAME_LEN]; /* Lua */ char ext_title_format_file[MAXLEN]; int use_ext_title_format; } options_t; enum { SONG_COLOR = 1, ACTIVE_SONG_COLOR }; // Mouse wheel commands on systray. enum { SYSTRAY_MW_CMD_DO_NOTHING, SYSTRAY_MW_CMD_VOLUME, SYSTRAY_MW_CMD_BALANCE, SYSTRAY_MW_CMD_SONG_POSITION, SYSTRAY_MW_CMD_NEXT_PREV_SONG }; // Mouse buttons commands on systray. enum { SYSTRAY_MB_CMD_PLAY_STOP_SONG, SYSTRAY_MB_CMD_PLAY_PAUSE_SONG, SYSTRAY_MB_CMD_PREV_SONG, SYSTRAY_MB_CMD_NEXT_SONG, SYSTRAY_MB_CMD_LAST }; enum { SYSTRAY_MB_COL_BUTTON, SYSTRAY_MB_COL_COMMAND, SYSTRAY_MB_LAST }; void create_options_window(void); void append_ms_pathlist(char * path, char * name); void options_store_watcher_start(void); void save_config(void); void load_config(void); void finalize_options(void); #endif /* _OPTIONS_H */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/options.c0000644000175000001440000050040311324131225013534 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: options.c 1095 2010-01-07 16:07:01Z quasireality $ */ #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_CDDA #ifdef HAVE_CDDB #define _TMP_HAVE_CDDB 1 #undef HAVE_CDDB #endif /* HAVE_CDDB */ #include #include #ifdef HAVE_CDDB #undef HAVE_CDDB #endif /* HAVE_CDDB */ #ifdef _TMP_HAVE_CDDB #define HAVE_CDDB 1 #undef _TMP_HAVE_CDDB #endif /* _TMP_HAVE_CDDB */ #endif /* HAVE_CDDA */ #ifdef HAVE_LUA #include "ext_title_format.h" #endif /* HAVE_LUA */ #ifdef HAVE_SRC #include #endif /* HAVE_SRC */ #include "common.h" #include "utils.h" #include "utils_gui.h" #include "gui_main.h" #include "music_browser.h" #include "store_file.h" #include "search.h" #include "playlist.h" #include "i18n.h" #include "options.h" #include "skin.h" options_t options; static int current_notebook_page = 0; extern int src_type_parsed; extern GtkWidget * main_window; extern GtkWidget * playlist_window; extern GtkWidget * playlist_color_indicator; extern GtkTooltips * aqualung_tooltips; extern PangoFontDescription *fd_playlist; extern PangoFontDescription *fd_browser; extern PangoFontDescription *fd_bigtimer; extern PangoFontDescription *fd_smalltimer; extern PangoFontDescription *fd_songtitle; extern PangoFontDescription *fd_songinfo; extern PangoFontDescription *fd_statusbar; extern int music_store_changed; extern GtkWidget * music_tree; extern GtkTreeStore * music_store; extern GtkWidget * conf__skin; int rva_is_enabled_shadow; int rva_env_shadow; float rva_refvol_shadow; float rva_steepness_shadow; int rva_use_averaging_shadow; int rva_use_linear_thresh_shadow; float rva_avg_linear_thresh_shadow; float rva_avg_stddev_thresh_shadow; float rva_no_rva_voladj_shadow; char ext_title_format_file_shadow[MAXLEN]; int appearance_changed; int reskin_flag; int restart_flag; int override_shadow; int track_name_in_bold_shadow; GtkWidget * options_window; GtkWidget * notebook; GtkWidget * entry_title; GtkWidget * entry_param; GtkWidget * check_enable_tooltips; GtkWidget * check_buttons_at_the_bottom; GtkWidget * check_disable_buttons_relief; GtkWidget * check_combine_play_pause; GtkWidget * check_main_window_always_on_top; GtkWidget * check_simple_view_in_fx; GtkWidget * check_united_minimization; GtkWidget * check_show_sn_title; GtkWidget * check_show_hidden; GtkWidget * check_tags_tab_first; GtkWidget * combo_cwidth; GtkWidget * check_magnify_smaller_images; GtkWidget * check_dont_show_cover; GtkWidget * check_show_cover_for_ms_tracks_only; #ifdef HAVE_SYSTRAY GtkWidget * check_use_systray; GtkWidget * check_systray_start_minimized; #if (GTK_CHECK_VERSION(2,15,0)) GtkWidget * get_mouse_button_window; GtkWidget * frame_systray_mouse_wheel; GtkWidget * frame_systray_mouse_buttons; GtkWidget * combo_systray_mouse_wheel_horizontal; GtkWidget * combo_systray_mouse_wheel_vertical; GtkListStore * systray_mouse_buttons_store; GtkListStore * systray_mouse_buttons_cmds_store; GtkTreeSelection * systray_mouse_buttons_selection; #endif /* GTK_CHECK_VERSION */ #endif /* HAVE_SYSTRAY */ GtkWidget * check_playlist_is_embedded; GtkWidget * check_autoplsave; GtkWidget * check_playlist_auto_save; GtkWidget * spin_playlist_auto_save; GtkWidget * check_playlist_is_tree; GtkWidget * check_playlist_always_show_tabs; GtkWidget * check_show_close_button_in_tab; GtkWidget * check_album_shuffle_mode; GtkWidget * check_enable_playlist_statusbar; GtkWidget * check_pl_statusbar_show_size; GtkWidget * check_show_rva_in_playlist; GtkWidget * check_show_length_in_playlist; GtkWidget * check_show_active_track_name_in_bold; GtkWidget * check_auto_roll_to_active_track; GtkWidget * check_enable_pl_rules_hint; GtkListStore * plistcol_store; GtkWidget * check_hide_comment_pane; GtkWidget * check_enable_mstore_toolbar; GtkWidget * check_enable_mstore_statusbar; GtkWidget * check_ms_statusbar_show_size; GtkWidget * check_expand_stores; GtkWidget * check_enable_ms_rules_hint; GtkWidget * check_enable_ms_tree_icons; GtkWidget * check_ms_confirm_removal; GtkListStore * ms_pathlist_store = NULL; GtkTreeSelection * ms_pathlist_select; GtkWidget * entry_ms_pathlist; #ifdef HAVE_LUA GtkWidget * entry_ext_title_format_file; #endif /* HAVE_LUA */ #ifdef HAVE_LADSPA GtkWidget * combo_ladspa; #endif /* HAVE_LADSPA */ #ifdef HAVE_SRC GtkWidget * combo_src; #endif /* HAVE_SRC */ GtkWidget * label_src; GtkWidget * check_rva_is_enabled; GtkWidget * rva_drawing_area; GdkPixmap * rva_pixmap = NULL; GtkWidget * rva_viewport; GtkWidget * combo_listening_env; GtkWidget * spin_refvol; GtkWidget * spin_steepness; GtkWidget * check_rva_use_averaging; GtkWidget * combo_threshold; GtkWidget * spin_linthresh; GtkWidget * spin_stdthresh; GtkWidget * spin_defvol; GtkObject * adj_refvol; GtkObject * adj_steepness; GtkObject * adj_linthresh; GtkObject * adj_stdthresh; GtkObject * adj_defvol; GtkWidget * label_listening_env; GtkWidget * label_refvol; GtkWidget * label_steepness; GtkWidget * label_threshold; GtkWidget * label_linthresh; GtkWidget * label_stdthresh; GtkWidget * label_defvol; GtkWidget * combo_replaygain; GtkWidget * check_batch_mpeg_add_id3v1; GtkWidget * check_batch_mpeg_add_id3v2; GtkWidget * check_batch_mpeg_add_ape; GtkWidget * check_meta_use_basename_only; GtkWidget * check_meta_rm_extension; GtkWidget * check_meta_us_to_space; GtkWidget * check_metaedit_auto_clone; #ifdef HAVE_CDDA GtkWidget * cdda_drive_speed_spinner; GtkWidget * check_cdda_mode_overlap; GtkWidget * check_cdda_mode_verify; GtkWidget * check_cdda_mode_neverskip; GtkWidget * check_cdda_force_drive_rescan; GtkWidget * check_cdda_add_to_playlist; GtkWidget * check_cdda_remove_from_playlist; GtkWidget * label_cdda_maxretries; GtkWidget * cdda_paranoia_maxretries_spinner; #endif /* HAVE_CDDA */ #ifdef HAVE_CDDB GtkWidget * cddb_server_entry; GtkWidget * cddb_tout_spinner; GtkWidget * cddb_email_entry; GtkWidget * cddb_local_entry; GtkWidget * cddb_local_check; GtkWidget * cddb_proto_combo; GtkWidget * cddb_label_proto; #endif /* HAVE_CDDB */ GtkWidget * inet_radio_direct; GtkWidget * inet_radio_proxy; GtkWidget * inet_frame; GtkWidget * inet_label_proxy; GtkWidget * inet_entry_proxy; GtkWidget * inet_label_proxy_port; GtkWidget * inet_spinner_proxy_port; GtkWidget * inet_label_noproxy_domains; GtkWidget * inet_entry_noproxy_domains; GtkWidget * inet_help_noproxy_domains; GtkWidget * inet_spinner_timeout; GtkWidget * check_disable_skin_support; GtkWidget * check_override_skin; #define DEFAULT_FONT_NAME "Sans 11" GtkWidget * entry_pl_font; GtkWidget * entry_ms_font; GtkWidget * entry_bt_font; GtkWidget * entry_st_font; GtkWidget * entry_songt_font; GtkWidget * entry_si_font; GtkWidget * entry_sb_font; GtkWidget * button_pl_font; GtkWidget * button_ms_font; GtkWidget * button_bt_font; GtkWidget * button_st_font; GtkWidget * button_songt_font; GtkWidget * button_si_font; GtkWidget * button_sb_font; GdkColor color; GtkWidget * color_picker; void draw_rva_diagram(void); void show_restart_info(void); void restart_active(GtkToggleButton *, gpointer); #ifdef HAVE_SYSTRAY #if (GTK_CHECK_VERSION(2,15,0)) void systray_mouse_button_add_clicked(GtkWidget *, gpointer); void systray_mouse_button_remove_clicked(GtkWidget *, gpointer); gchar * systray_mb_cmd_names[SYSTRAY_MB_CMD_LAST]; gint systray_mb_col_command_combo_cmd = -1; int get_mb_window_button; #endif /* GTK_CHECK_VERSION */ #endif /* HAVE_SYSTRAY */ void load_systray_options(xmlDocPtr, xmlNodePtr); void save_systray_options(xmlDocPtr, xmlNodePtr); GtkListStore * restart_list_store = NULL; void open_font_desc(void) { if (fd_playlist) { pango_font_description_free(fd_playlist); fd_playlist = NULL; } if (fd_browser) { pango_font_description_free(fd_browser); fd_browser = NULL; } if (fd_bigtimer) { pango_font_description_free(fd_bigtimer); fd_bigtimer = NULL; } if (fd_smalltimer) { pango_font_description_free(fd_smalltimer); fd_smalltimer = NULL; } if (fd_songtitle) { pango_font_description_free(fd_songtitle); fd_songtitle = NULL; } if (fd_songinfo) { pango_font_description_free(fd_songinfo); fd_songinfo = NULL; } if (fd_statusbar) { pango_font_description_free(fd_statusbar); fd_statusbar = NULL; } if (options.override_skin_settings) { fd_playlist = pango_font_description_from_string(options.playlist_font); fd_browser = pango_font_description_from_string(options.browser_font); fd_bigtimer = pango_font_description_from_string(options.bigtimer_font); fd_smalltimer = pango_font_description_from_string(options.smalltimer_font); fd_songtitle = pango_font_description_from_string(options.songtitle_font); fd_songinfo = pango_font_description_from_string(options.songinfo_font); fd_statusbar = pango_font_description_from_string(options.statusbar_font); } } int diff_option_from_toggle(GtkWidget * widget, int opt) { gboolean act = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); return (act && !opt) || (!act && opt); } void music_store_remove_unset_stores(void) { int i; GtkTreeIter iter; GtkTreeIter iter2; i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &iter, NULL, i++)) { int j; int has; store_t * data; store_data_t * store_data; gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter, MS_COL_DATA, &data, -1); if (data->type != STORE_TYPE_FILE) { continue; } store_data = (store_data_t *)data; j = 0; has = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(ms_pathlist_store), &iter2, NULL, j++)) { char * file; gtk_tree_model_get(GTK_TREE_MODEL(ms_pathlist_store), &iter2, 0, &file, -1); if (strcmp(store_data->file, file) == 0) { if (access(file, R_OK) == 0) { has = 1; } g_free(file); break; } g_free(file); } if (!has) { if (store_data->dirty) { int ret; char * name; gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter, MS_COL_NAME, &name, -1); ret = message_dialog(_("Settings"), options_window, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, NULL, _("Do you want to save store \"%s\" before " "removing from Music Store?"), name + 1); if (ret == GTK_RESPONSE_YES) { store_file_save(&iter); } else { music_store_mark_saved(&iter); } g_free(name); } store_file_remove_store(&iter); --i; } } } void music_store_remove_non_existent_stores(void) { int i; GtkTreeIter iter; i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &iter, NULL, i++)) { store_t * data; store_data_t * store_data; gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter, MS_COL_DATA, &data, -1); if (data->type != STORE_TYPE_FILE) { continue; } store_data = (store_data_t *)data; if (access(store_data->file, R_OK) != 0) { if (!store_data->dirty) { store_file_remove_store(&iter); --i; } } } } void music_store_add_new_stores() { int i; GtkTreeIter iter; GtkTreeIter iter2; i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(ms_pathlist_store), &iter, NULL, i++)) { char * file; int j; int has; char sort[16]; snprintf(sort, 15, "%03d", i+1); gtk_tree_model_get(GTK_TREE_MODEL(ms_pathlist_store), &iter, 0, &file, -1); j = 0; has = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &iter2, NULL, j++)) { store_t * data; store_data_t * store_data; gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter2, MS_COL_DATA, &data, -1); if (data->type != STORE_TYPE_FILE) { continue; } store_data = (store_data_t *)data; if (strcmp(file, store_data->file) == 0) { gtk_tree_store_set(music_store, &iter2, MS_COL_SORT, sort, -1); if (access(store_data->file, W_OK) == 0) { store_data->readonly = 0; } else { store_data->readonly = 1; } has = 1; break; } } if (!has) { store_file_load(file, sort); } g_free(file); } } gboolean options_store_watcher_cb(gpointer data) { music_store_remove_non_existent_stores(); music_store_add_new_stores(); return TRUE; } void options_store_watcher_start(void) { aqualung_timeout_add(5000, options_store_watcher_cb, NULL); } void options_window_accept(void) { int i; GtkTreeIter iter; int title_format_changed = 0; #ifdef HAVE_LUA char * ext_title; ext_title = (char *)gtk_entry_get_text(GTK_ENTRY(entry_ext_title_format_file)); strncpy(options.ext_title_format_file, ext_title, MAXLEN-1); setup_extended_title_formatting(); #endif /* HAVE_LUA */ if (restart_flag) { show_restart_info(); } /* General */ if (diff_option_from_toggle(check_meta_use_basename_only, options.meta_use_basename_only) || diff_option_from_toggle(check_meta_rm_extension, options.meta_rm_extension) || diff_option_from_toggle(check_meta_us_to_space, options.meta_us_to_space) || strcmp(options.title_format, gtk_entry_get_text(GTK_ENTRY(entry_title)))) { title_format_changed = 1; } strncpy(options.title_format, gtk_entry_get_text(GTK_ENTRY(entry_title)), MAXLEN-1); strncpy(options.default_param, gtk_entry_get_text(GTK_ENTRY(entry_param)), MAXLEN-1); set_option_from_toggle(check_enable_tooltips, &options.enable_tooltips); aqualung_tooltips_set_enabled(options.enable_tooltips); #ifdef HAVE_LADSPA set_option_from_toggle(check_simple_view_in_fx, &options.simple_view_in_fx_shadow); #endif /* HAVE_LADSPA */ set_option_from_toggle(check_united_minimization, &options.united_minimization); set_option_from_toggle(check_show_hidden, &options.show_hidden); set_option_from_toggle(check_tags_tab_first, &options.tags_tab_first); set_option_from_combo(combo_cwidth, &options.cover_width); set_option_from_toggle(check_magnify_smaller_images, &options.magnify_smaller_images); set_option_from_toggle(check_dont_show_cover, &options.dont_show_cover); set_option_from_toggle(check_show_cover_for_ms_tracks_only, &options.show_cover_for_ms_tracks_only); options.magnify_smaller_images = !options.magnify_smaller_images; if(options.dont_show_cover) { hide_cover_thumbnail(); } set_option_from_toggle(check_disable_buttons_relief, &options.disable_buttons_relief); set_option_from_toggle(check_combine_play_pause, &options.combine_play_pause_shadow); set_option_from_toggle(check_main_window_always_on_top, &options.main_window_always_on_top); set_option_from_toggle(check_show_sn_title, &options.show_sn_title); #ifdef HAVE_SYSTRAY set_option_from_toggle(check_use_systray, &options.use_systray); set_option_from_toggle(check_systray_start_minimized, &options.systray_start_minimized); #if (GTK_CHECK_VERSION(2,15,0)) set_option_from_combo(combo_systray_mouse_wheel_horizontal, &options.systray_mouse_wheel_horizontal); set_option_from_combo(combo_systray_mouse_wheel_vertical, &options.systray_mouse_wheel_vertical); options.systray_mouse_buttons_count = 0; if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(systray_mouse_buttons_store), &iter)) { do { ++options.systray_mouse_buttons_count; } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(systray_mouse_buttons_store), &iter)); } options.systray_mouse_buttons = realloc(options.systray_mouse_buttons, options.systray_mouse_buttons_count * sizeof(mouse_button_command_t)); if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(systray_mouse_buttons_store), &iter)) { i = 0; do { gtk_tree_model_get(GTK_TREE_MODEL(systray_mouse_buttons_store), &iter, SYSTRAY_MB_COL_BUTTON, &options.systray_mouse_buttons[i].button_nr, SYSTRAY_MB_COL_COMMAND, &options.systray_mouse_buttons[i].command, -1); ++i; } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(systray_mouse_buttons_store), &iter)); } #endif /* GTK_CHECK_VERSION */ #endif /* HAVE_SYSTRAY */ /* Playlist */ set_option_from_toggle(check_autoplsave, &options.auto_save_playlist); set_option_from_toggle(check_playlist_auto_save, &options.playlist_auto_save); playlist_auto_save_reset(); set_option_from_spin(spin_playlist_auto_save, &options.playlist_auto_save_int); set_option_from_toggle(check_playlist_is_embedded, &options.playlist_is_embedded_shadow); set_option_from_toggle(check_buttons_at_the_bottom, &options.buttons_at_the_bottom_shadow); set_option_from_toggle(check_playlist_is_tree, &options.playlist_is_tree); set_option_from_toggle(check_playlist_always_show_tabs, &options.playlist_always_show_tabs); set_option_from_toggle(check_show_close_button_in_tab, &options.playlist_show_close_button_in_tab); playlist_show_hide_close_buttons(options.playlist_show_close_button_in_tab); set_option_from_toggle(check_album_shuffle_mode, &options.album_shuffle_mode); set_option_from_toggle(check_enable_playlist_statusbar, &options.enable_playlist_statusbar_shadow); set_option_from_toggle(check_pl_statusbar_show_size, &options.pl_statusbar_show_size); set_option_from_toggle(check_show_rva_in_playlist, &options.show_rva_in_playlist); set_option_from_toggle(check_show_length_in_playlist, &options.show_length_in_playlist); set_option_from_toggle(check_show_active_track_name_in_bold, &options.show_active_track_name_in_bold); if (!options.show_active_track_name_in_bold) { playlist_disable_bold_font(); } set_option_from_toggle(check_auto_roll_to_active_track, &options.auto_roll_to_active_track); set_option_from_toggle(check_enable_pl_rules_hint, &options.enable_pl_rules_hint); /* Music Store */ set_option_from_toggle(check_hide_comment_pane, &options.hide_comment_pane_shadow); set_option_from_toggle(check_enable_mstore_toolbar, &options.enable_mstore_toolbar_shadow); set_option_from_toggle(check_enable_mstore_statusbar, &options.enable_mstore_statusbar_shadow); set_option_from_toggle(check_ms_statusbar_show_size, &options.ms_statusbar_show_size); set_option_from_toggle(check_expand_stores, &options.autoexpand_stores); set_option_from_toggle(check_enable_ms_rules_hint, &options.enable_ms_rules_hint); gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(music_tree), options.enable_ms_rules_hint); set_option_from_toggle(check_enable_ms_tree_icons, &options.enable_ms_tree_icons_shadow); set_option_from_toggle(check_ms_confirm_removal, &options.ms_confirm_removal); /* RVA */ options.rva_is_enabled = rva_is_enabled_shadow; options.rva_env = rva_env_shadow; options.rva_refvol = rva_refvol_shadow; options.rva_steepness = rva_steepness_shadow; options.rva_use_averaging = rva_use_averaging_shadow; options.rva_use_linear_thresh = rva_use_linear_thresh_shadow; options.rva_avg_linear_thresh = rva_avg_linear_thresh_shadow; options.rva_avg_stddev_thresh = rva_avg_stddev_thresh_shadow; options.rva_no_rva_voladj = rva_no_rva_voladj_shadow; /* Metadata */ set_option_from_combo(combo_replaygain, &options.replaygain_tag_to_use); set_option_from_toggle(check_batch_mpeg_add_id3v1, &options.batch_mpeg_add_id3v1); set_option_from_toggle(check_batch_mpeg_add_id3v2, &options.batch_mpeg_add_id3v2); set_option_from_toggle(check_batch_mpeg_add_ape, &options.batch_mpeg_add_ape); set_option_from_toggle(check_metaedit_auto_clone, &options.metaedit_auto_clone); set_option_from_toggle(check_meta_use_basename_only, &options.meta_use_basename_only); set_option_from_toggle(check_meta_rm_extension, &options.meta_rm_extension); set_option_from_toggle(check_meta_us_to_space, &options.meta_us_to_space); if (title_format_changed) { playlist_reset_display_names(); } /* CDDA */ #ifdef HAVE_CDDA set_option_from_spin(cdda_drive_speed_spinner, &options.cdda_drive_speed); options.cdda_paranoia_mode = (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check_cdda_mode_overlap)) ? PARANOIA_MODE_OVERLAP : 0) | (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check_cdda_mode_verify)) ? PARANOIA_MODE_VERIFY : 0) | (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check_cdda_mode_neverskip)) ? PARANOIA_MODE_NEVERSKIP : 0); set_option_from_spin(cdda_paranoia_maxretries_spinner, &options.cdda_paranoia_maxretries); set_option_from_toggle(check_cdda_force_drive_rescan, &options.cdda_force_drive_rescan); set_option_from_toggle(check_cdda_add_to_playlist, &options.cdda_add_to_playlist); set_option_from_toggle(check_cdda_remove_from_playlist, &options.cdda_remove_from_playlist); #endif /* HAVE_CDDA */ /* CDDB */ #ifdef HAVE_CDDB set_option_from_entry(cddb_server_entry, options.cddb_server, MAXLEN); set_option_from_spin(cddb_tout_spinner, &options.cddb_timeout); set_option_from_entry(cddb_email_entry, options.cddb_email, MAXLEN); set_option_from_entry(cddb_local_entry, options.cddb_local, MAXLEN); set_option_from_toggle(cddb_local_check, &options.cddb_cache_only); set_option_from_combo(cddb_proto_combo, &options.cddb_use_http); #endif /* HAVE_CDDB */ /* Internet */ set_option_from_toggle(inet_radio_proxy, &options.inet_use_proxy); set_option_from_entry(inet_entry_proxy, options.inet_proxy, MAXLEN); set_option_from_spin(inet_spinner_proxy_port, &options.inet_proxy_port); set_option_from_entry(inet_entry_noproxy_domains, options.inet_noproxy_domains, MAXLEN); set_option_from_spin(inet_spinner_timeout, &options.inet_timeout); /* Appearance */ set_option_from_toggle(check_disable_skin_support, &options.disable_skin_support_settings); set_option_from_toggle(check_override_skin, &options.override_skin_settings); set_option_from_entry(entry_pl_font, options.playlist_font, MAX_FONTNAME_LEN); set_option_from_entry(entry_ms_font, options.browser_font, MAX_FONTNAME_LEN); set_option_from_entry(entry_bt_font, options.bigtimer_font, MAX_FONTNAME_LEN); set_option_from_entry(entry_st_font, options.smalltimer_font, MAX_FONTNAME_LEN); set_option_from_entry(entry_songt_font, options.songtitle_font, MAX_FONTNAME_LEN); set_option_from_entry(entry_si_font, options.songinfo_font, MAX_FONTNAME_LEN); set_option_from_entry(entry_sb_font, options.statusbar_font, MAX_FONTNAME_LEN); /* refresh GUI */ for (i = 0; i < 3; i++) { gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(plistcol_store), &iter, NULL, i); gtk_tree_model_get(GTK_TREE_MODEL(plistcol_store), &iter, 1, options.plcol_idx + i, -1); } playlist_reorder_columns_all(options.plcol_idx); if (!track_name_in_bold_shadow && options.show_active_track_name_in_bold == 1) { reskin_flag = 1; track_name_in_bold_shadow = 0; } if (appearance_changed) { /* apply fonts */ open_font_desc(); main_window_set_font(1); music_browser_set_font(1); playlist_set_font(1); playlist_set_color(); reskin_flag = 1; } if (!options.override_skin_settings && override_shadow) { reskin_flag = 1; override_shadow = 0; } music_store_remove_unset_stores(); music_store_add_new_stores(); set_buttons_relief(); refresh_displays(); gtk_window_set_keep_above(GTK_WINDOW(main_window), options.main_window_always_on_top); music_store_selection_changed(STORE_TYPE_ALL); playlist_content_changed(playlist_get_current()); playlist_selection_changed(playlist_get_current()); save_config(); } #ifdef HAVE_LADSPA void changed_ladspa_prepost(GtkWidget * widget, gpointer * data) { int status = gtk_combo_box_get_active(GTK_COMBO_BOX(combo_ladspa)); options.ladspa_is_postfader = status; } #endif /* HAVE_LADSPA */ #ifdef HAVE_SRC void changed_src_type(GtkWidget * widget, gpointer * data) { options.src_type = gtk_combo_box_get_active(GTK_COMBO_BOX(combo_src)); gtk_label_set_text(GTK_LABEL(label_src), src_get_description(options.src_type)); set_src_type_label(options.src_type); } #endif /* HAVE_SRC */ void check_rva_is_enabled_toggled(GtkWidget * widget, gpointer * data) { if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check_rva_is_enabled))) { rva_is_enabled_shadow = 1; gtk_widget_set_sensitive(combo_listening_env, TRUE); gtk_widget_set_sensitive(label_listening_env, TRUE); gtk_widget_set_sensitive(spin_refvol, TRUE); gtk_widget_set_sensitive(label_refvol, TRUE); gtk_widget_set_sensitive(spin_steepness, TRUE); gtk_widget_set_sensitive(label_steepness, TRUE); gtk_widget_set_sensitive(check_rva_use_averaging, TRUE); gtk_widget_set_sensitive(spin_defvol, TRUE); gtk_widget_set_sensitive(label_defvol, TRUE); if (rva_use_averaging_shadow) { gtk_widget_set_sensitive(combo_threshold, TRUE); gtk_widget_set_sensitive(label_threshold, TRUE); gtk_widget_set_sensitive(spin_linthresh, TRUE); gtk_widget_set_sensitive(label_linthresh, TRUE); gtk_widget_set_sensitive(spin_stdthresh, TRUE); gtk_widget_set_sensitive(label_stdthresh, TRUE); } } else { rva_is_enabled_shadow = 0; gtk_widget_set_sensitive(combo_listening_env, FALSE); gtk_widget_set_sensitive(label_listening_env, FALSE); gtk_widget_set_sensitive(spin_refvol, FALSE); gtk_widget_set_sensitive(label_refvol, FALSE); gtk_widget_set_sensitive(spin_steepness, FALSE); gtk_widget_set_sensitive(label_steepness, FALSE); gtk_widget_set_sensitive(check_rva_use_averaging, FALSE); gtk_widget_set_sensitive(combo_threshold, FALSE); gtk_widget_set_sensitive(label_threshold, FALSE); gtk_widget_set_sensitive(spin_linthresh, FALSE); gtk_widget_set_sensitive(label_linthresh, FALSE); gtk_widget_set_sensitive(spin_stdthresh, FALSE); gtk_widget_set_sensitive(label_stdthresh, FALSE); gtk_widget_set_sensitive(spin_defvol, FALSE); gtk_widget_set_sensitive(label_defvol, FALSE); } draw_rva_diagram(); } void check_rva_use_averaging_toggled(GtkWidget * widget, gpointer * data) { if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check_rva_use_averaging))) { rva_use_averaging_shadow = 1; gtk_widget_set_sensitive(combo_threshold, TRUE); gtk_widget_set_sensitive(label_threshold, TRUE); gtk_widget_set_sensitive(spin_linthresh, TRUE); gtk_widget_set_sensitive(label_linthresh, TRUE); gtk_widget_set_sensitive(spin_stdthresh, TRUE); gtk_widget_set_sensitive(label_stdthresh, TRUE); } else { rva_use_averaging_shadow = 0; gtk_widget_set_sensitive(combo_threshold, FALSE); gtk_widget_set_sensitive(label_threshold, FALSE); gtk_widget_set_sensitive(spin_linthresh, FALSE); gtk_widget_set_sensitive(label_linthresh, FALSE); gtk_widget_set_sensitive(spin_stdthresh, FALSE); gtk_widget_set_sensitive(label_stdthresh, FALSE); } } void changed_listening_env(GtkWidget * widget, gpointer * data) { rva_env_shadow = gtk_combo_box_get_active(GTK_COMBO_BOX(combo_listening_env)); switch (rva_env_shadow) { case 0: /* Audiophile */ gtk_adjustment_set_value(GTK_ADJUSTMENT(adj_refvol), -12.0f); gtk_adjustment_set_value(GTK_ADJUSTMENT(adj_steepness), 1.0f); break; case 1: /* Living room */ gtk_adjustment_set_value(GTK_ADJUSTMENT(adj_refvol), -12.0f); gtk_adjustment_set_value(GTK_ADJUSTMENT(adj_steepness), 0.7f); break; case 2: /* Office */ gtk_adjustment_set_value(GTK_ADJUSTMENT(adj_refvol), -12.0f); gtk_adjustment_set_value(GTK_ADJUSTMENT(adj_steepness), 0.4f); break; case 3: /* Noisy workshop */ gtk_adjustment_set_value(GTK_ADJUSTMENT(adj_refvol), -12.0f); gtk_adjustment_set_value(GTK_ADJUSTMENT(adj_steepness), 0.1f); break; default: fprintf(stderr, "programmer error: options.c/changed_listening_env(): " "invalid rva_env_shadow value.\nPlease report this to the programmers!\n"); break; } } void draw_rva_diagram(void) { int i; int width = rva_viewport->allocation.width - 4; int height = rva_viewport->allocation.height - 4; int dw = width / 24; int dh = height / 24; int xoffs = (width - 24*dw) / 2 - 1; int yoffs = (height - 24*dh) / 2 - 1; float volx, voly; int px1, py1, px2, py2; #if (GTK_CHECK_VERSION(2,8,0)) cairo_t *rva_cr = NULL; rva_cr = gdk_cairo_create (rva_drawing_area->window); if (rva_cr != NULL) { cairo_set_source_rgb (rva_cr, 0.0, 0.0, 0.0); cairo_paint (rva_cr); cairo_set_line_width (rva_cr, 1.0); if (rva_is_enabled_shadow) { cairo_set_source_rgb (rva_cr, 10000 / 65536.0, 10000 / 65536.0, 10000 / 65536.0); } else { cairo_set_source_rgb (rva_cr, 5000 / 65536.0, 5000 / 65536.0, 5000 / 65536.0); } cairo_set_antialias (rva_cr, CAIRO_ANTIALIAS_NONE); for (i = 0; i <= 24; i++) { cairo_move_to (rva_cr, xoffs + i * dw, yoffs); cairo_line_to (rva_cr, xoffs + i * dw, yoffs + 24 * dh); cairo_move_to (rva_cr, xoffs, yoffs + i * dh); cairo_line_to (rva_cr, xoffs + 24 * dw, yoffs + i * dh); } cairo_stroke (rva_cr); cairo_set_antialias (rva_cr, CAIRO_ANTIALIAS_DEFAULT); if (rva_is_enabled_shadow) { cairo_set_source_rgb (rva_cr, 0.0, 0.0, 1.0); } else { cairo_set_source_rgb (rva_cr, 0.0, 0.0, 30000 / 65536.0); } cairo_move_to (rva_cr, xoffs, yoffs + 24 * dh); cairo_line_to (rva_cr, xoffs + 24 * dw, yoffs); cairo_stroke (rva_cr); if (rva_is_enabled_shadow) { cairo_set_source_rgb (rva_cr, 1.0, 0.0, 0.0); } else { cairo_set_source_rgb (rva_cr, 30000 / 65536.0, 0.0, 0.0); } volx = -24.0f; voly = volx + (volx - rva_refvol_shadow) * (rva_steepness_shadow - 1.0f); px1 = xoffs; py1 = yoffs - (voly * dh); volx = 0.0f; voly = volx + (volx - rva_refvol_shadow) * (rva_steepness_shadow - 1.0f); px2 = xoffs + 24*dw; py2 = yoffs - (voly * dh); cairo_move_to (rva_cr, px1, py1); cairo_line_to (rva_cr, px2, py2); cairo_stroke (rva_cr); cairo_destroy (rva_cr); } #else GdkGC * gc; GdkColor fg_color; gdk_draw_rectangle(rva_pixmap, rva_drawing_area->style->black_gc, TRUE, 0, 0, rva_drawing_area->allocation.width, rva_drawing_area->allocation.height); gc = gdk_gc_new(rva_pixmap); if (rva_is_enabled_shadow) { fg_color.red = 10000; fg_color.green = 10000; fg_color.blue = 10000; } else { fg_color.red = 5000; fg_color.green = 5000; fg_color.blue = 5000; } gdk_gc_set_rgb_fg_color(gc, &fg_color); for (i = 0; i <= 24; i++) { gdk_draw_line(rva_pixmap, gc, xoffs + i * dw, yoffs, xoffs + i * dw, yoffs + 24 * dh); gdk_draw_line(rva_pixmap, gc, xoffs, yoffs + i * dh, xoffs + 24 * dw, yoffs + i * dh); } if (rva_is_enabled_shadow) { fg_color.red = 0; fg_color.green = 0; fg_color.blue = 65535; } else { fg_color.red = 0; fg_color.green = 0; fg_color.blue = 30000; } gdk_gc_set_rgb_fg_color(gc, &fg_color); gdk_draw_line(rva_pixmap, gc, xoffs, yoffs + 24 * dh, xoffs + 24 * dw, yoffs); if (rva_is_enabled_shadow) { fg_color.red = 65535; fg_color.green = 0; fg_color.blue = 0; } else { fg_color.red = 30000; fg_color.green = 0; fg_color.blue = 0; } gdk_gc_set_rgb_fg_color(gc, &fg_color); volx = -24.0f; voly = volx + (volx - rva_refvol_shadow) * (rva_steepness_shadow - 1.0f); px1 = xoffs; py1 = yoffs - (voly * dh); volx = 0.0f; voly = volx + (volx - rva_refvol_shadow) * (rva_steepness_shadow - 1.0f); px2 = xoffs + 24*dw; py2 = yoffs - (voly * dh); gdk_draw_line(rva_pixmap, gc, px1, py1, px2, py2); gdk_draw_drawable(rva_drawing_area->window, rva_drawing_area->style->fg_gc[GTK_WIDGET_STATE(rva_drawing_area)], rva_pixmap, 0, 0, 0, 0, width, height); g_object_unref(gc); #endif /* GTK_CHECK_VERSION */ } void refvol_changed(GtkWidget * widget, gpointer * data) { rva_refvol_shadow = gtk_adjustment_get_value(GTK_ADJUSTMENT(widget)); draw_rva_diagram(); } void steepness_changed(GtkWidget * widget, gpointer * data) { rva_steepness_shadow = gtk_adjustment_get_value(GTK_ADJUSTMENT(widget)); draw_rva_diagram(); } static gint rva_configure_event(GtkWidget * widget, GdkEventConfigure * event) { #if (!GTK_CHECK_VERSION(2,8,0)) if (rva_pixmap) g_object_unref(rva_pixmap); rva_pixmap = gdk_pixmap_new(widget->window, widget->allocation.width, widget->allocation.height, -1); gdk_draw_rectangle(rva_pixmap, widget->style->black_gc, TRUE, 0, 0, widget->allocation.width, widget->allocation.height); #endif /* GTK_CHECK_VERSION */ draw_rva_diagram(); return TRUE; } static gint rva_expose_event(GtkWidget * widget, GdkEventExpose * event) { #if (GTK_CHECK_VERSION(2,8,0)) draw_rva_diagram(); #else gdk_draw_drawable(widget->window, widget->style->fg_gc[GTK_WIDGET_STATE (widget)], rva_pixmap, event->area.x, event->area.y, event->area.x, event->area.y, event->area.width, event->area.height); #endif /* GTK_CHECK_VERSION */ return FALSE; } void changed_threshold(GtkWidget * widget, gpointer * data) { rva_use_linear_thresh_shadow = gtk_combo_box_get_active(GTK_COMBO_BOX(combo_threshold)); } void linthresh_changed(GtkWidget * widget, gpointer * data) { rva_avg_linear_thresh_shadow = gtk_adjustment_get_value(GTK_ADJUSTMENT(widget)); } void stdthresh_changed(GtkWidget * widget, gpointer * data) { rva_avg_stddev_thresh_shadow = gtk_adjustment_get_value(GTK_ADJUSTMENT(widget)) / 100.0f; } void defvol_changed(GtkWidget * widget, gpointer * data) { rva_no_rva_voladj_shadow = gtk_adjustment_get_value(GTK_ADJUSTMENT(widget)); } void show_restart_info(void) { GtkWidget * list; GtkWidget * viewport; GtkCellRenderer * renderer; GtkTreeViewColumn * column; list = gtk_tree_view_new_with_model(GTK_TREE_MODEL(restart_list_store)); renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes("", renderer, "text", 0, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(list), column); gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(list), FALSE); viewport = gtk_viewport_new(NULL, NULL); gtk_container_add(GTK_CONTAINER(viewport), list); message_dialog(_("Settings"), options_window, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, viewport, _("You will need to restart Aqualung for the following changes to take effect:")); } void appearance_font_select(GtkWidget * widget, gpointer data) { gchar *s; GtkWidget *font_selector; gint response; font_selector = gtk_font_selection_dialog_new(_("Select a font...")); gtk_window_set_modal(GTK_WINDOW(font_selector), TRUE); gtk_window_set_transient_for(GTK_WINDOW(font_selector), GTK_WINDOW(options_window)); gtk_font_selection_dialog_set_font_name(GTK_FONT_SELECTION_DIALOG(font_selector), gtk_entry_get_text(GTK_ENTRY((GtkWidget *)data))); gtk_widget_show (font_selector); response = aqualung_dialog_run (GTK_DIALOG (font_selector)); if (response == GTK_RESPONSE_OK) { s = gtk_font_selection_dialog_get_font_name (GTK_FONT_SELECTION_DIALOG(font_selector)); gtk_entry_set_text(GTK_ENTRY((GtkWidget *)data), s); g_free (s); } appearance_changed = 1; gtk_widget_destroy (font_selector); } void restart_active(GtkToggleButton * togglebutton, gpointer data) { GtkTreeIter iter; char * text; int i = 0; restart_flag = 1; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(restart_list_store), &iter, NULL, i++)) { gtk_tree_model_get(GTK_TREE_MODEL(restart_list_store), &iter, 0, &text, -1); if (!strcmp(text, (char *)data)) { gtk_list_store_remove(restart_list_store, &iter); if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(restart_list_store), &iter)) { restart_flag = 0; } return; } } gtk_list_store_append(restart_list_store, &iter); gtk_list_store_set(restart_list_store, &iter, 0, (char *)data, -1); } void set_sensitive_part(void) { GtkWidget *sensitive_table[] = { entry_ms_font, entry_pl_font, entry_bt_font, entry_st_font, entry_songt_font, entry_si_font, entry_sb_font, button_ms_font, button_pl_font, button_bt_font, button_st_font, button_songt_font, button_si_font, button_sb_font, color_picker }; gboolean state; gint items, n; state = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check_override_skin)); items = sizeof(sensitive_table) / sizeof(GtkWidget*); for (n = 0; n < items; n++) { gtk_widget_set_sensitive(sensitive_table[n], state); } } void cb_toggle_disable_skin_support(GtkToggleButton *togglebutton, gpointer user_data) { appearance_changed = 1; if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check_disable_skin_support)) == TRUE) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_override_skin), TRUE); gtk_widget_set_sensitive(check_override_skin, FALSE); restart_active(togglebutton, _("Disable skin support")); } else { gtk_widget_set_sensitive(check_override_skin, TRUE); } } void cb_toggle_override_skin(GtkToggleButton *togglebutton, gpointer user_data) { appearance_changed = 1; set_sensitive_part(); } void color_selected(GtkColorButton *widget, gpointer user_data) { GdkColor c; gchar str[MAX_COLORNAME_LEN]; appearance_changed = 1; gtk_color_button_get_color(widget, &c); sprintf(str, "#%02X%02X%02X", c.red * 256 / 65536, c.green * 256 / 65536, c.blue * 256 / 65536); if (GPOINTER_TO_INT(user_data) == SONG_COLOR) { strncpy(options.song_color, str, MAX_COLORNAME_LEN-1); } else { strncpy(options.activesong_color, str, MAX_COLORNAME_LEN-1); } } GtkWidget * create_notebook_tab(char * text, char * imgfile) { GtkWidget * vbox; GdkPixbuf * pixbuf; GtkWidget * image; GtkWidget * label; char path[MAXLEN]; vbox = gtk_vbox_new(FALSE, 0); label = gtk_label_new(text); gtk_box_pack_end(GTK_BOX(vbox), label, FALSE, FALSE, 0); sprintf(path, "%s/%s", AQUALUNG_DATADIR, imgfile); pixbuf = gdk_pixbuf_new_from_file(path, NULL); if (pixbuf) { image = gtk_image_new_from_pixbuf(pixbuf); gtk_box_pack_end(GTK_BOX(vbox), image, FALSE, FALSE, 0); } gtk_widget_show_all(vbox); return vbox; } void refresh_ms_pathlist_clicked(GtkWidget * widget, gpointer * data) { GtkTreeIter iter; char * path; int i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(ms_pathlist_store), &iter, NULL, i++)) { gtk_tree_model_get(GTK_TREE_MODEL(ms_pathlist_store), &iter, 0, &path, -1); if (access(path, R_OK | W_OK) == 0) { gtk_list_store_set(ms_pathlist_store, &iter, 2, _("rw"), -1); } else if (access(path, R_OK) == 0) { gtk_list_store_set(ms_pathlist_store, &iter, 2, _("r"), -1); } else { gtk_list_store_set(ms_pathlist_store, &iter, 2, _("unreachable"), -1); } g_free(path); } } #ifdef HAVE_LUA void browse_ext_title_format_file_clicked(GtkButton * button, gpointer data) { file_chooser_with_entry(_("Please select a Programable Title Format File."), options_window, GTK_FILE_CHOOSER_ACTION_OPEN, FILE_CHOOSER_FILTER_ETF, (GtkWidget *)data, ext_title_format_file_shadow); } #endif /* HAVE_LUA */ void browse_ms_pathlist_clicked(GtkButton * button, gpointer data) { file_chooser_with_entry(_("Please select a Music Store database."), options_window, GTK_FILE_CHOOSER_ACTION_OPEN, FILE_CHOOSER_FILTER_STORE, (GtkWidget *)data, options.storedir); } void append_ms_pathlist(char * path, char * name) { GtkTreeIter iter; gtk_list_store_append(ms_pathlist_store, &iter); gtk_list_store_set(ms_pathlist_store, &iter, 0, path, 1, name, -1); refresh_ms_pathlist_clicked(NULL, NULL); } void add_ms_pathlist_clicked(GtkButton * button, gpointer * data) { const char * pname; char name[MAXLEN]; char * path; GtkTreeIter iter; int i; struct stat st_file; pname = gtk_entry_get_text(GTK_ENTRY(entry_ms_pathlist)); if (pname[0] == '\0') { browse_ms_pathlist_clicked(button, entry_ms_pathlist); return; } if (pname[0] == '~') { snprintf(name, MAXLEN - 1, "%s%s", options.home, pname + 1); } else if (pname[0] == '/') { strncpy(name, pname, MAXLEN - 1); } else { message_dialog(_("Warning"), options_window, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, NULL, _("Paths must either be absolute or starting with a tilde.")); return; } if ((path = g_filename_from_utf8(name, -1, NULL, NULL, NULL)) == NULL) { return; } if (stat(path, &st_file) != -1 && S_ISDIR(st_file.st_mode)) { return; } i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(ms_pathlist_store), &iter, NULL, i++)) { char * p; gtk_tree_model_get(GTK_TREE_MODEL(ms_pathlist_store), &iter, 0, &p, -1); if (!strcmp(p, path)) { message_dialog(_("Warning"), options_window, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, NULL, _("The specified store has already been added to the list.")); g_free(p); g_free(path); return; } g_free(p); } gtk_entry_set_text(GTK_ENTRY(entry_ms_pathlist), ""); append_ms_pathlist(path, name); strncpy(options.storedir, name, MAXLEN-1); g_free(path); } void remove_ms_pathlist_clicked(GtkWidget * widget, gpointer data) { GtkTreeIter iter; int i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(ms_pathlist_store), &iter, NULL, i++)) { if (gtk_tree_selection_iter_is_selected(ms_pathlist_select, &iter)) { gtk_list_store_remove(ms_pathlist_store, &iter); --i; } } } void check_playlist_auto_save_cb(GtkWidget * widget, gpointer data) { if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check_playlist_auto_save))) { gtk_widget_set_sensitive(spin_playlist_auto_save, TRUE); } else { gtk_widget_set_sensitive(spin_playlist_auto_save, FALSE); } } void display_help(char * text) { message_dialog(_("Help"), options_window, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, NULL, text); } void display_title_format_help(void) { display_help(_("\nThe template string you enter here will be used to " "construct a single title line from an Artist, a Record " "and a Track name. These are denoted by %%%%a, %%%%r and %%%%t, " "respectively.\n")); } #ifdef HAVE_LUA void display_ext_title_format_help(void) { display_help(_("\nThe file you enter/choose here will set the Lua program to use " "to format the title. See the Aqualung manual for details. " "Here is a quick example of what you can use in the file:\n\n" "function playlist_title()\n" " return m('artist') .. '-' .. m('title') .. ' (' .. m('album') .. ') (' .. i('filename') .. ')'\n" "end")); } #endif /* HAVE_LUA */ void display_implict_command_line_help(void) { display_help(_("\nThe string you enter here will be parsed as a command " "line before parsing the actual command line parameters. " "What you enter here will act as a default setting and may " "or may not be overridden from the 'real' command line.\n\n" "Example: enter '-o alsa -R' below to use ALSA output " "running realtime as a default.\n")); } void display_pathlist_help(void) { display_help(_("Paths must either be absolute or starting with a tilde, which will be expanded to the user's home directory.\n\n" "Drag and drop entries in the list to set the store order in the Music Store.")); } #ifdef HAVE_CDDA void display_cdda_drive_speed_help(void) { display_help(_("\nSet the drive speed for CD playing in CD-ROM speed units. " "One speed unit equals to 176 kBps raw data reading speed. " "Warning: not all drives honor this setting.\n\n" "Lower speed usually means less drive noise. However, " "when using Paranoia error correction modes for increased " "accuracy, generally much larger speeds are required to " "prevent buffer underruns (and thus audible drop-outs).\n\n" "Please note that these settings do not apply to CD Ripping, " "which always happens with maximum available speed and " "with error correction modes manually set before every run.")); } void display_cdda_force_drive_rescan_help(void) { display_help(_("\nMost drives let Aqualung know when a CD has been inserted " "or removed by providing a 'media changed' flag. However, " "some drives don't set this flag properly, and thus it may " "happen that a newly inserted CD remains unnoticed to " "Aqualung. In such cases, enabling this option should help.")); } void cdda_toggled(GtkWidget * widget, gpointer * data) { gtk_widget_set_sensitive(cdda_paranoia_maxretries_spinner, !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check_cdda_mode_neverskip))); gtk_widget_set_sensitive(label_cdda_maxretries, !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check_cdda_mode_neverskip))); } #endif /* HAVE_CDDA */ void inet_radio_direct_toggled(GtkWidget * widget, gpointer * data) { gboolean state = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(inet_radio_direct)); gtk_widget_set_sensitive(inet_frame, !state); } void display_inet_help_noproxy_domains(void) { display_help(_("\nHere you should enter a comma-separated list of domains\n" "that should be accessed without using the proxy set above.\n" "Example: localhost, .localdomain, .my.domain.com")); } void playlist_embedded_cb(GtkToggleButton * togglebutton, gpointer data) { gtk_widget_set_sensitive(GTK_WIDGET(data), gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(togglebutton))); restart_active(togglebutton, _("Embed playlist into main window")); } #ifdef HAVE_SYSTRAY void systray_support_cb(GtkToggleButton * togglebutton, gpointer data) { gboolean systray_active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(togglebutton)); gtk_widget_set_sensitive(GTK_WIDGET(check_systray_start_minimized), systray_active); #if (GTK_CHECK_VERSION(2,15,0)) gtk_widget_set_sensitive(GTK_WIDGET(frame_systray_mouse_wheel), systray_active); gtk_widget_set_sensitive(GTK_WIDGET(frame_systray_mouse_buttons), systray_active); #endif /* GTK_CHECK_VERSION */ restart_active(togglebutton, _("Enable systray")); } #if (GTK_CHECK_VERSION(2,15,0)) GtkWidget * setup_combo_with_label(GtkBox * box, char * label_text) { GtkWidget * hbox; GtkWidget * hbox_s; GtkWidget * label; GtkWidget * combo; hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(box, hbox, FALSE, TRUE, 5); label = gtk_label_new(label_text); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); hbox_s = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), hbox_s, TRUE, TRUE, 3); combo = gtk_combo_box_new_text (); gtk_box_pack_start(GTK_BOX(hbox), combo, FALSE, FALSE, 0); return combo; } void fill_mouse_wheel_combo(GtkComboBox * combo) { gtk_combo_box_append_text (combo, _("Do nothing")); gtk_combo_box_append_text (combo, _("Change volume")); gtk_combo_box_append_text (combo, _("Change balance")); gtk_combo_box_append_text (combo, _("Change song position")); gtk_combo_box_append_text (combo, _("Change current song")); } void get_mouse_button_text(int button_number, char * text_buffer, int buffer_size) { switch (button_number) { case 1: g_snprintf(text_buffer, buffer_size, _("Left button")); break; case 2: g_snprintf(text_buffer, buffer_size, _("Middle button")); break; case 3: g_snprintf(text_buffer, buffer_size, _("Right button")); break; default: g_snprintf(text_buffer, buffer_size, "%s %d", _("Button"), button_number); break; } } gboolean get_mouse_button_button_press_cb(GtkWidget * widget, GdkEventButton * event, gpointer user_data) { GtkTreeIter iter; gint button_number; gboolean set_button = TRUE; int i = 0; gchar buf[30]; // Don't allow setting Left or Right mouse buttons (they are reserved). if (event->button == 1 || event->button == 3) { message_dialog(_("Warning"), get_mouse_button_window, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, NULL, _("Left and right mouse buttons are reserved.")); set_button = FALSE; } else { // Don't allow duplicate buttons. while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(systray_mouse_buttons_store), &iter, NULL, i++)) { gtk_tree_model_get(GTK_TREE_MODEL(systray_mouse_buttons_store), &iter, SYSTRAY_MB_COL_BUTTON, &button_number, -1); if (button_number == event->button) { message_dialog(_("Warning"), get_mouse_button_window, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, NULL, _("This button is already assigned.")); set_button = FALSE; break; } } } if (set_button) { get_mouse_button_text(event->button, buf, sizeof(buf)); gtk_label_set_text(GTK_LABEL(user_data), buf); get_mb_window_button = event->button; } return set_button; } void setup_get_mouse_button_window(void) { GtkWidget * vbox_main; GtkWidget * vbox; GtkWidget * frame; GtkWidget * eventbox; GtkWidget * label; GtkWidget * combo; GtkWidget * alignment; GtkTreeIter iter; int i; int ret; get_mouse_button_window = gtk_dialog_new_with_buttons( _("Add mouse button command"), GTK_WINDOW(options_window), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL); gtk_window_set_position(GTK_WINDOW(get_mouse_button_window), GTK_WIN_POS_CENTER); gtk_dialog_set_default_response(GTK_DIALOG(get_mouse_button_window), GTK_RESPONSE_ACCEPT); gtk_container_set_border_width(GTK_CONTAINER(get_mouse_button_window), 5); vbox_main = GTK_DIALOG(get_mouse_button_window)->vbox; gtk_box_set_spacing(GTK_BOX(vbox_main), 8); eventbox = gtk_event_box_new(); gtk_event_box_set_above_child(GTK_EVENT_BOX(eventbox), TRUE); gtk_event_box_set_visible_window(GTK_EVENT_BOX(eventbox), FALSE); gtk_box_pack_start(GTK_BOX(vbox_main), eventbox, FALSE, TRUE, 0); frame = gtk_frame_new(_("Mouse button")); gtk_container_add(GTK_CONTAINER(eventbox), frame); vbox = gtk_vbox_new(FALSE, 0); gtk_container_add(GTK_CONTAINER(frame), vbox); alignment = gtk_alignment_new (0.5, 0.5, 1, 1); gtk_box_pack_start (GTK_BOX (vbox), alignment, FALSE, TRUE, 0); gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 30, 30, 20, 20); label = gtk_label_new(_("Click here to set mouse button")); gtk_container_add(GTK_CONTAINER(alignment), label); g_signal_connect(G_OBJECT(eventbox), "button-press-event", G_CALLBACK(get_mouse_button_button_press_cb), label); frame = gtk_frame_new(_("Command")); gtk_box_pack_start(GTK_BOX(vbox_main), frame, FALSE, TRUE, 0); vbox = gtk_vbox_new(FALSE, 3); gtk_container_set_border_width(GTK_CONTAINER(vbox), 10); gtk_container_add(GTK_CONTAINER(frame), vbox); combo = gtk_combo_box_new_text (); gtk_container_add(GTK_CONTAINER(vbox), combo); for (i = 0; i < SYSTRAY_MB_CMD_LAST; i++) { gtk_combo_box_append_text (GTK_COMBO_BOX(combo), systray_mb_cmd_names[i]); } gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0); gtk_widget_show_all (get_mouse_button_window); get_mb_window_button = 0; ret = aqualung_dialog_run(GTK_DIALOG(get_mouse_button_window)); if (ret == GTK_RESPONSE_ACCEPT) { i = gtk_combo_box_get_active(GTK_COMBO_BOX(combo)); if (get_mb_window_button > 0 && i >= 0) { gtk_list_store_append (systray_mouse_buttons_store, &iter); gtk_list_store_set (systray_mouse_buttons_store, &iter, SYSTRAY_MB_COL_BUTTON, get_mb_window_button, SYSTRAY_MB_COL_COMMAND, i, -1); } } gtk_widget_destroy(get_mouse_button_window); } void systray_mouse_button_add_clicked(GtkWidget * widget, gpointer data) { setup_get_mouse_button_window(); } void systray_mouse_button_remove_clicked(GtkWidget * widget, gpointer data) { GtkTreeIter iter; int i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(systray_mouse_buttons_store), &iter, NULL, i++)) { if (gtk_tree_selection_iter_is_selected(systray_mouse_buttons_selection, &iter)) { gtk_list_store_remove(systray_mouse_buttons_store, &iter); --i; } } } void systray_mb_col_button_datafunc(GtkTreeViewColumn *tree_column, GtkCellRenderer *cell_renderer, GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data) { gchar buf[30]; int button_number; gtk_tree_model_get(tree_model, iter, SYSTRAY_MB_COL_BUTTON, &button_number, -1); get_mouse_button_text(button_number, buf, sizeof(buf)); g_object_set(cell_renderer, "text", buf, NULL); } void systray_mb_col_command_datafunc(GtkTreeViewColumn *tree_column, GtkCellRenderer *cell_renderer, GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data) { gint command; gtk_tree_model_get(tree_model, iter, SYSTRAY_MB_COL_COMMAND, &command, -1); if (command >= 0 && command < SYSTRAY_MB_CMD_LAST) { g_object_set(cell_renderer, "text", systray_mb_cmd_names[command], NULL); } } void systray_mb_col_command_combo_changed_cb(GtkCellRendererCombo * combo, gchar * path_string, GtkTreeIter * new_iter, gpointer user_data) { // Get integer command number from the combobox. gtk_tree_model_get(GTK_TREE_MODEL(systray_mouse_buttons_cmds_store), new_iter, 1, &systray_mb_col_command_combo_cmd, -1); } void systray_mb_col_command_combo_edited_cb(GtkCellRendererText * cell_renderer, gchar * path, gchar * selection, gpointer user_data) { GtkTreeIter iter; if (gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(systray_mouse_buttons_store), &iter, path)) { if (systray_mb_col_command_combo_cmd >= 0 && systray_mb_col_command_combo_cmd < SYSTRAY_MB_CMD_LAST) { gtk_list_store_set (systray_mouse_buttons_store, &iter, SYSTRAY_MB_COL_COMMAND, systray_mb_col_command_combo_cmd, -1); } } systray_mb_col_command_combo_cmd = -1; } #endif /* GTK_CHECK_VERSION */ #endif /* HAVE_SYSTRAY */ void create_options_window(void) { int ret; GtkWidget * vbox_general; GtkWidget * nbook_general; GtkWidget * frame_title; GtkWidget * frame_param; GtkWidget * frame_misc; GtkWidget * frame_cart; GtkWidget * hbox_param; GtkWidget * vbox_misc; GtkWidget * vbox_cart; GtkWidget * vbox_appearance; GtkWidget * vbox_miscellaneous_tab; #ifdef HAVE_SYSTRAY GtkWidget * vbox_systray; #if (GTK_CHECK_VERSION(2,15,0)) GtkWidget * systray_mb_list; GtkWidget * button; #endif /* HAVE_SYSTRAY */ #endif /* GTK_CHECK_VERSION */ #ifdef HAVE_LUA GtkWidget * browse_ext_title_format_file; GtkWidget * help_btn_ext_title; #endif /* HAVE_LUA */ GtkWidget * vbox_pl; GtkWidget * vbox_ms; GtkWidget * frame_ms_pathlist; GtkWidget * ms_pathlist_view; GtkWidget * vbox_ms_pathlist; GtkWidget * hbox_ms_pathlist; GtkWidget * hbox_ms_pathlist_2; GtkWidget * add_ms_pathlist; GtkWidget * browse_ms_pathlist; GtkWidget * remove_ms_pathlist; GtkWidget * refresh_ms_pathlist; GtkWidget * frame_plistcol; GtkWidget * vbox_plistcol; GtkWidget * label_plistcol; GtkWidget * viewport; GtkWidget * scrolled_win; GtkCellRenderer * renderer; GtkTreeViewColumn * column; GtkTreeIter iter; GtkWidget * plistcol_list; GtkWidget * label; GtkWidget * vbox_dsp; GtkWidget * frame_ladspa; GtkWidget * frame_src; GtkWidget * frame_fonts; GtkWidget * frame_colors; GtkWidget * vbox_ladspa; GtkWidget * vbox_src; GtkWidget * table_fonts; GtkWidget * vbox_colors; GtkWidget * vbox_rva; GtkWidget * table_rva; GtkWidget * label_cwidth; GtkWidget * hbox_cwidth; GtkWidget * vbox_meta; GtkWidget * hbox_meta; GtkWidget * frame_meta; GtkWidget * vbox_meta2; #ifdef HAVE_CDDA GtkWidget * table_cdda; GtkWidget * help_btn_cdda_drive_speed; GtkWidget * help_btn_cdda_force_drive_rescan; GtkWidget * frame_cdda; GtkWidget * vbox_cdda; GtkWidget * hbox_cdda; #endif /* HAVE_CDDA */ #ifdef HAVE_CDDB GtkWidget * table_cddb; #endif /* HAVE_CDDB */ GtkWidget * vbox_inet; GtkWidget * table_inet; GtkWidget * inet_hbox_timeout; GtkWidget * inet_label_timeout; GtkSizeGroup * label_size; GtkWidget * hbox; GtkWidget * vbox; GtkWidget * hbox_s; GtkWidget * help_btn_title; GtkWidget * help_btn_param; GtkWidget * help_pathlist; GtkWidget * alignment; #ifdef HAVE_LADSPA int status; #endif /* HAVE_LADSPA */ int i; restart_flag = 0; reskin_flag = 0; appearance_changed = 0; if (options.ext_title_format_file[0] == '\0') { strncpy(ext_title_format_file_shadow, options.confdir, MAXLEN-1); } else { strncpy(ext_title_format_file_shadow, options.ext_title_format_file, MAXLEN-1); } if (!restart_list_store) { restart_list_store = gtk_list_store_new(1, G_TYPE_STRING); } else { gtk_list_store_clear(restart_list_store); } refresh_ms_pathlist_clicked(NULL, NULL); options_window = gtk_dialog_new_with_buttons(_("Settings"), GTK_WINDOW(main_window), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL); gtk_window_set_position(GTK_WINDOW(options_window), GTK_WIN_POS_CENTER); gtk_dialog_set_default_response(GTK_DIALOG(options_window), GTK_RESPONSE_ACCEPT); gtk_container_set_border_width(GTK_CONTAINER(options_window), 5); notebook = gtk_notebook_new(); gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_LEFT); gtk_container_add(GTK_CONTAINER(GTK_DIALOG(options_window)->vbox), notebook); label_size = gtk_size_group_new(GTK_SIZE_GROUP_BOTH); /* "General" notebook page */ vbox_general = gtk_vbox_new(FALSE, 3); gtk_container_set_border_width(GTK_CONTAINER(vbox_general), 8); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox_general, create_notebook_tab(_("General"), "general.png")); nbook_general = gtk_notebook_new(); gtk_box_pack_start(GTK_BOX(vbox_general), nbook_general, FALSE, TRUE, 0); /* General/Main window page */ vbox = gtk_vbox_new(FALSE, 3); gtk_container_set_border_width(GTK_CONTAINER(vbox), 5); gtk_notebook_append_page(GTK_NOTEBOOK(nbook_general), vbox, gtk_label_new(_("Main window"))); check_disable_buttons_relief = gtk_check_button_new_with_label(_("Disable control buttons relief")); gtk_widget_set_name(check_disable_buttons_relief, "check_on_notebook"); if (options.disable_buttons_relief) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_disable_buttons_relief), TRUE); } gtk_box_pack_start(GTK_BOX(vbox), check_disable_buttons_relief, FALSE, FALSE, 0); check_combine_play_pause = gtk_check_button_new_with_label(_("Combine play and pause buttons")); gtk_widget_set_name(check_combine_play_pause, "check_on_notebook"); if (options.combine_play_pause_shadow) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_combine_play_pause), TRUE); } gtk_box_pack_start(GTK_BOX(vbox), check_combine_play_pause, FALSE, FALSE, 0); g_signal_connect (G_OBJECT (check_combine_play_pause), "toggled", G_CALLBACK (restart_active), _("Combine play and pause buttons")); check_main_window_always_on_top = gtk_check_button_new_with_label(_("Keep main window always on top")); gtk_widget_set_name(check_main_window_always_on_top, "check_on_notebook"); if (options.main_window_always_on_top) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_main_window_always_on_top), TRUE); } gtk_box_pack_start(GTK_BOX(vbox), check_main_window_always_on_top, FALSE, FALSE, 0); check_show_sn_title = gtk_check_button_new_with_label(_("Show song name in the main window's title")); gtk_widget_set_name(check_show_sn_title, "check_on_notebook"); if (options.show_sn_title) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_show_sn_title), TRUE); } gtk_box_pack_start(GTK_BOX(vbox), check_show_sn_title, FALSE, FALSE, 0); /* General/Title format page */ vbox = gtk_vbox_new(FALSE, 3); gtk_container_set_border_width(GTK_CONTAINER(vbox), 5); gtk_notebook_append_page(GTK_NOTEBOOK(nbook_general), vbox, gtk_label_new(_("Title Format"))); frame_title = gtk_frame_new(_("Title Format")); gtk_box_pack_start(GTK_BOX(vbox), frame_title, FALSE, TRUE, 5); hbox = gtk_hbox_new(FALSE, 3); gtk_container_set_border_width(GTK_CONTAINER(hbox), 5); gtk_container_add(GTK_CONTAINER(frame_title), hbox); entry_title = gtk_entry_new(); gtk_entry_set_max_length(GTK_ENTRY(entry_title), MAXLEN - 1); gtk_entry_set_text(GTK_ENTRY(entry_title), options.title_format); gtk_box_pack_start(GTK_BOX(hbox), entry_title, TRUE, TRUE, 0); help_btn_title = gtk_button_new_from_stock (GTK_STOCK_HELP); g_signal_connect(help_btn_title, "clicked", G_CALLBACK(display_title_format_help), NULL); gtk_box_pack_start(GTK_BOX(hbox), help_btn_title, FALSE, FALSE, 5); #ifdef HAVE_LUA frame_title = gtk_frame_new(_("Programmable title format file")); gtk_box_pack_start(GTK_BOX(vbox), frame_title, FALSE, TRUE, 5); hbox = gtk_hbox_new(FALSE, 3); gtk_container_set_border_width(GTK_CONTAINER(hbox), 5); gtk_container_add(GTK_CONTAINER(frame_title), hbox); entry_ext_title_format_file = gtk_entry_new(); gtk_entry_set_max_length(GTK_ENTRY(entry_ext_title_format_file), MAXLEN - 1); gtk_entry_set_text(GTK_ENTRY(entry_ext_title_format_file), options.ext_title_format_file); gtk_box_pack_start(GTK_BOX(hbox), entry_ext_title_format_file, TRUE, TRUE, 2); browse_ext_title_format_file = gui_stock_label_button(_("Browse"), GTK_STOCK_OPEN); gtk_container_set_border_width(GTK_CONTAINER(browse_ext_title_format_file), 2); g_signal_connect (G_OBJECT(browse_ext_title_format_file), "clicked", G_CALLBACK(browse_ext_title_format_file_clicked), (gpointer)entry_ext_title_format_file); gtk_box_pack_start(GTK_BOX(hbox), browse_ext_title_format_file, FALSE, FALSE, 5); help_btn_ext_title = gtk_button_new_from_stock(GTK_STOCK_HELP); g_signal_connect(help_btn_ext_title, "clicked", G_CALLBACK(display_ext_title_format_help), NULL); gtk_box_pack_end(GTK_BOX(hbox), help_btn_ext_title, FALSE, FALSE, 5); #endif /* HAVE_LUA */ /* General/Systray page */ #ifdef HAVE_SYSTRAY vbox_systray = gtk_vbox_new(FALSE, 3); gtk_container_set_border_width(GTK_CONTAINER(vbox_systray), 5); gtk_notebook_append_page(GTK_NOTEBOOK(nbook_general), vbox_systray, gtk_label_new(_("Systray"))); check_use_systray = gtk_check_button_new_with_label(_("Enable systray")); gtk_widget_set_name(check_use_systray, "check_on_notebook"); if (options.use_systray) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_use_systray), TRUE); } gtk_box_pack_start(GTK_BOX(vbox_systray), check_use_systray, FALSE, FALSE, 0); alignment = gtk_alignment_new (0.5, 0.5, 1, 1); gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 0, 16, 0); gtk_box_pack_start (GTK_BOX (vbox_systray), alignment, FALSE, TRUE, 0); check_systray_start_minimized = gtk_check_button_new_with_label(_("Start minimized")); gtk_widget_set_name(check_systray_start_minimized, "check_on_notebook"); if (options.systray_start_minimized) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_systray_start_minimized), TRUE); } gtk_container_add (GTK_CONTAINER (alignment), check_systray_start_minimized); g_signal_connect (G_OBJECT (check_use_systray), "toggled", G_CALLBACK (systray_support_cb), NULL); #if (GTK_CHECK_VERSION(2,15,0)) systray_mb_cmd_names[SYSTRAY_MB_CMD_PLAY_STOP_SONG] = _("Play/Stop song"); systray_mb_cmd_names[SYSTRAY_MB_CMD_PLAY_PAUSE_SONG] = _("Play/Pause song"); systray_mb_cmd_names[SYSTRAY_MB_CMD_PREV_SONG] = _("Previous song"); systray_mb_cmd_names[SYSTRAY_MB_CMD_NEXT_SONG] = _("Next song"); frame_systray_mouse_wheel = gtk_frame_new(_("Mouse wheel")); gtk_box_pack_start(GTK_BOX(vbox_systray), frame_systray_mouse_wheel, FALSE, TRUE, 5); vbox = gtk_vbox_new(FALSE, 3); gtk_container_set_border_width(GTK_CONTAINER(vbox), 10); gtk_container_add(GTK_CONTAINER(frame_systray_mouse_wheel), vbox); combo_systray_mouse_wheel_vertical = setup_combo_with_label(GTK_BOX(vbox), _("Vertical mouse wheel:")); fill_mouse_wheel_combo(GTK_COMBO_BOX (combo_systray_mouse_wheel_vertical)); gtk_combo_box_set_active (GTK_COMBO_BOX (combo_systray_mouse_wheel_vertical), options.systray_mouse_wheel_vertical); combo_systray_mouse_wheel_horizontal = setup_combo_with_label(GTK_BOX(vbox), _("Horizontal mouse wheel:")); fill_mouse_wheel_combo(GTK_COMBO_BOX (combo_systray_mouse_wheel_horizontal)); gtk_combo_box_set_active (GTK_COMBO_BOX (combo_systray_mouse_wheel_horizontal), options.systray_mouse_wheel_horizontal); frame_systray_mouse_buttons = gtk_frame_new(_("Mouse buttons")); gtk_box_pack_start(GTK_BOX(vbox_systray), frame_systray_mouse_buttons, FALSE, TRUE, 5); vbox = gtk_vbox_new(FALSE, 3); gtk_container_set_border_width(GTK_CONTAINER(vbox), 8); gtk_container_add(GTK_CONTAINER(frame_systray_mouse_buttons), vbox); scrolled_win = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_win), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_widget_set_size_request(scrolled_win, 100, 100); gtk_box_pack_start(GTK_BOX(vbox), scrolled_win, FALSE, TRUE, 5); /* Mouse buttons table */ systray_mouse_buttons_store = gtk_list_store_new (SYSTRAY_MB_LAST, G_TYPE_INT, /* Button nr */ G_TYPE_INT); /* Command index */ for (i = 0; i < options.systray_mouse_buttons_count; i++) { gtk_list_store_append (systray_mouse_buttons_store, &iter); gtk_list_store_set (systray_mouse_buttons_store, &iter, SYSTRAY_MB_COL_BUTTON, options.systray_mouse_buttons[i].button_nr, SYSTRAY_MB_COL_COMMAND, options.systray_mouse_buttons[i].command, -1); } systray_mb_list = gtk_tree_view_new_with_model(GTK_TREE_MODEL(systray_mouse_buttons_store)); systray_mouse_buttons_selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(systray_mb_list)); gtk_tree_selection_set_mode(systray_mouse_buttons_selection, GTK_SELECTION_MULTIPLE); gtk_tree_view_set_enable_search(GTK_TREE_VIEW(systray_mb_list), FALSE); GTK_WIDGET_UNSET_FLAGS(GTK_WIDGET(systray_mb_list), GTK_CAN_FOCUS); gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled_win), systray_mb_list); // First mouse buttons column. renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes(_("Button"), renderer, NULL); gtk_tree_view_column_set_cell_data_func( column, renderer, systray_mb_col_button_datafunc, NULL, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(systray_mb_list), column); // Second mouse buttons column. renderer = gtk_cell_renderer_combo_new(); systray_mouse_buttons_cmds_store = gtk_list_store_new ( 2, G_TYPE_STRING, /* Command description */ G_TYPE_INT); /* Command index */ for (i = 0; i < SYSTRAY_MB_CMD_LAST; i++) { gtk_list_store_append (systray_mouse_buttons_cmds_store, &iter); gtk_list_store_set (systray_mouse_buttons_cmds_store, &iter, 0, systray_mb_cmd_names[i], 1, i, -1); } g_object_set(G_OBJECT (renderer), "model", systray_mouse_buttons_cmds_store, "text-column", 0, "editable", TRUE, "has-entry", FALSE, NULL); g_signal_connect(G_OBJECT(renderer), "changed", G_CALLBACK(systray_mb_col_command_combo_changed_cb), NULL); g_signal_connect(G_OBJECT(renderer), "edited", G_CALLBACK(systray_mb_col_command_combo_edited_cb), NULL); column = gtk_tree_view_column_new_with_attributes(_("Command"), renderer, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(systray_mb_list), column); gtk_tree_view_column_set_cell_data_func( column, renderer, systray_mb_col_command_datafunc, NULL, NULL); hbox = gtk_hbox_new(FALSE, 3); gtk_container_set_border_width(GTK_CONTAINER(hbox), 0); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); button = gui_stock_label_button(_("Add"), GTK_STOCK_ADD); g_signal_connect (G_OBJECT(button), "clicked", G_CALLBACK(systray_mouse_button_add_clicked), NULL); gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); button = gui_stock_label_button(_("Remove"), GTK_STOCK_REMOVE); g_signal_connect (G_OBJECT(button), "clicked", G_CALLBACK(systray_mouse_button_remove_clicked), NULL); gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); gtk_widget_set_sensitive(check_systray_start_minimized, options.use_systray); gtk_widget_set_sensitive(frame_systray_mouse_wheel, options.use_systray); gtk_widget_set_sensitive(frame_systray_mouse_buttons, options.use_systray); #endif /* GTK_CHECK_VERSION */ #endif /* HAVE_SYSTRAY */ /* General/Miscellaneous page */ vbox_miscellaneous_tab = gtk_vbox_new(FALSE, 3); gtk_container_set_border_width(GTK_CONTAINER(vbox_miscellaneous_tab), 5); gtk_notebook_append_page(GTK_NOTEBOOK(nbook_general), vbox_miscellaneous_tab, gtk_label_new(_("Miscellaneous"))); frame_param = gtk_frame_new(_("Implicit command line")); gtk_box_pack_start(GTK_BOX(vbox_miscellaneous_tab), frame_param, FALSE, TRUE, 5); hbox_param = gtk_hbox_new(FALSE, 3); gtk_container_set_border_width(GTK_CONTAINER(hbox_param), 5); gtk_container_add(GTK_CONTAINER(frame_param), hbox_param); entry_param = gtk_entry_new(); gtk_entry_set_max_length(GTK_ENTRY(entry_param), MAXLEN - 1); gtk_entry_set_text(GTK_ENTRY(entry_param), options.default_param); gtk_box_pack_start(GTK_BOX(hbox_param), entry_param, TRUE, TRUE, 0); help_btn_param = gtk_button_new_from_stock (GTK_STOCK_HELP); g_signal_connect(help_btn_param, "clicked", G_CALLBACK(display_implict_command_line_help), NULL); gtk_box_pack_start(GTK_BOX(hbox_param), help_btn_param, FALSE, FALSE, 5); frame_cart = gtk_frame_new(_("Cover art")); gtk_box_pack_start(GTK_BOX(vbox_miscellaneous_tab), frame_cart, FALSE, TRUE, 5); vbox_cart = gtk_vbox_new(FALSE, 3); gtk_container_set_border_width(GTK_CONTAINER(vbox_cart), 10); gtk_container_add(GTK_CONTAINER(frame_cart), vbox_cart); hbox_cwidth = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox_cart), hbox_cwidth, FALSE, FALSE, 0); label_cwidth = gtk_label_new(_("Default cover width:")); gtk_box_pack_start(GTK_BOX(hbox_cwidth), label_cwidth, FALSE, FALSE, 0); hbox_s = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox_cwidth), hbox_s, TRUE, TRUE, 3); combo_cwidth = gtk_combo_box_new_text (); gtk_box_pack_start(GTK_BOX(hbox_cwidth), combo_cwidth, FALSE, FALSE, 0); gtk_combo_box_append_text (GTK_COMBO_BOX (combo_cwidth), _("50 pixels")); gtk_combo_box_append_text (GTK_COMBO_BOX (combo_cwidth), _("100 pixels")); gtk_combo_box_append_text (GTK_COMBO_BOX (combo_cwidth), _("200 pixels")); gtk_combo_box_append_text (GTK_COMBO_BOX (combo_cwidth), _("300 pixels")); gtk_combo_box_append_text (GTK_COMBO_BOX (combo_cwidth), _("use browser window width")); gtk_combo_box_set_active (GTK_COMBO_BOX (combo_cwidth), options.cover_width); check_magnify_smaller_images = gtk_check_button_new_with_label(_("Do not magnify images with smaller width")); gtk_widget_set_name(check_magnify_smaller_images, "check_on_notebook"); if (!options.magnify_smaller_images) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_magnify_smaller_images), TRUE); } gtk_box_pack_start(GTK_BOX(vbox_cart), check_magnify_smaller_images, FALSE, FALSE, 0); check_show_cover_for_ms_tracks_only = gtk_check_button_new_with_label(_("Show cover thumbnail for Music Store tracks only")); gtk_widget_set_name(check_show_cover_for_ms_tracks_only, "check_on_notebook"); if (options.show_cover_for_ms_tracks_only) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_show_cover_for_ms_tracks_only), TRUE); } gtk_box_pack_start(GTK_BOX(vbox_cart), check_show_cover_for_ms_tracks_only, FALSE, FALSE, 0); check_dont_show_cover = gtk_check_button_new_with_label(_("Don't show cover thumbnail in the main window")); gtk_widget_set_name(check_dont_show_cover, "check_on_notebook"); if (options.dont_show_cover) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_dont_show_cover), TRUE); } gtk_box_pack_start(GTK_BOX(vbox_cart), check_dont_show_cover, FALSE, FALSE, 0); frame_misc = gtk_frame_new(_("Miscellaneous")); gtk_box_pack_start(GTK_BOX(vbox_miscellaneous_tab), frame_misc, FALSE, TRUE, 0); vbox_misc = gtk_vbox_new(FALSE, 3); gtk_container_set_border_width(GTK_CONTAINER(vbox_misc), 8); gtk_container_add(GTK_CONTAINER(frame_misc), vbox_misc); check_enable_tooltips = gtk_check_button_new_with_label(_("Enable tooltips")); gtk_widget_set_name(check_enable_tooltips, "check_on_notebook"); if (options.enable_tooltips) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_enable_tooltips), TRUE); } gtk_box_pack_start(GTK_BOX(vbox_misc), check_enable_tooltips, FALSE, FALSE, 0); #ifdef HAVE_LADSPA check_simple_view_in_fx = gtk_check_button_new_with_label(_("Simple view in LADSPA patch builder")); gtk_widget_set_name(check_simple_view_in_fx, "check_on_notebook"); if (options.simple_view_in_fx_shadow) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_simple_view_in_fx), TRUE); } gtk_box_pack_start(GTK_BOX(vbox_misc), check_simple_view_in_fx, FALSE, FALSE, 0); g_signal_connect(G_OBJECT (check_simple_view_in_fx), "toggled", G_CALLBACK (restart_active), _("Simple view in LADSPA patch builder")); #endif /* HAVE_LADSPA */ check_united_minimization = gtk_check_button_new_with_label(_("United windows minimization")); gtk_widget_set_name(check_united_minimization, "check_on_notebook"); if (options.united_minimization) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_united_minimization), TRUE); } gtk_box_pack_start(GTK_BOX(vbox_misc), check_united_minimization, FALSE, FALSE, 0); check_show_hidden = gtk_check_button_new_with_label(_("Show hidden files and directories in file choosers")); gtk_widget_set_name(check_show_hidden, "check_on_notebook"); if (options.show_hidden) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_show_hidden), TRUE); } gtk_box_pack_start(GTK_BOX(vbox_misc), check_show_hidden, FALSE, FALSE, 0); check_tags_tab_first = gtk_check_button_new_with_label(_("Show tags tab first in the file info dialog")); gtk_widget_set_name(check_tags_tab_first, "check_on_notebook"); if (options.tags_tab_first) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_tags_tab_first), TRUE); } gtk_box_pack_start(GTK_BOX(vbox_misc), check_tags_tab_first, FALSE, FALSE, 0); /* "Playlist" notebook page */ vbox_pl = gtk_vbox_new(FALSE, 3); gtk_container_set_border_width(GTK_CONTAINER(vbox_pl), 8); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox_pl, create_notebook_tab(_("Playlist"), "playlist.png")); check_playlist_is_embedded = gtk_check_button_new_with_label(_("Embed playlist into main window")); gtk_widget_set_name(check_playlist_is_embedded, "check_on_notebook"); if (options.playlist_is_embedded_shadow) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_playlist_is_embedded), TRUE); } gtk_box_pack_start(GTK_BOX(vbox_pl), check_playlist_is_embedded, FALSE, TRUE, 0); alignment = gtk_alignment_new (0.5, 0.5, 1, 1); gtk_box_pack_start (GTK_BOX (vbox_pl), alignment, FALSE, TRUE, 0); gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 0, 16, 0); check_buttons_at_the_bottom = gtk_check_button_new_with_label(_("Put control buttons at the bottom of playlist")); gtk_widget_set_name(check_buttons_at_the_bottom, "check_on_notebook"); if (options.buttons_at_the_bottom_shadow) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_buttons_at_the_bottom), TRUE); } if (options.playlist_is_embedded_shadow) { gtk_widget_set_sensitive(check_buttons_at_the_bottom, TRUE); } else { gtk_widget_set_sensitive(check_buttons_at_the_bottom, FALSE); } gtk_container_add (GTK_CONTAINER (alignment), check_buttons_at_the_bottom); g_signal_connect (G_OBJECT (check_buttons_at_the_bottom), "toggled", G_CALLBACK (restart_active), _("Put control buttons at the bottom of playlist")); g_signal_connect (G_OBJECT (check_playlist_is_embedded), "toggled", G_CALLBACK (playlist_embedded_cb), check_buttons_at_the_bottom); check_autoplsave = gtk_check_button_new_with_label(_("Save and restore the playlist on exit/startup")); gtk_widget_set_name(check_autoplsave, "check_on_notebook"); if (options.auto_save_playlist) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_autoplsave), TRUE); } gtk_box_pack_start(GTK_BOX(vbox_pl), check_autoplsave, FALSE, TRUE, 0); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox_pl), hbox, FALSE, TRUE, 0); check_playlist_auto_save = gtk_check_button_new_with_label(_("Save playlist periodically [min]:")); gtk_widget_set_name(check_playlist_auto_save, "check_on_notebook"); g_signal_connect(G_OBJECT(check_playlist_auto_save), "toggled", G_CALLBACK(check_playlist_auto_save_cb), NULL); gtk_box_pack_start(GTK_BOX(hbox), check_playlist_auto_save, FALSE, TRUE, 0); spin_playlist_auto_save = gtk_spin_button_new_with_range(1, 60, 1); gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin_playlist_auto_save), options.playlist_auto_save_int); gtk_box_pack_start(GTK_BOX(hbox), spin_playlist_auto_save, FALSE, TRUE, 10); if (options.playlist_auto_save) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_playlist_auto_save), TRUE); } else { gtk_widget_set_sensitive(spin_playlist_auto_save, FALSE); } check_playlist_is_tree = gtk_check_button_new_with_label(_("Album mode is the default when adding entire records")); gtk_widget_set_name(check_playlist_is_tree, "check_on_notebook"); if (options.playlist_is_tree) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_playlist_is_tree), TRUE); } gtk_box_pack_start(GTK_BOX(vbox_pl), check_playlist_is_tree, FALSE, TRUE, 0); check_playlist_always_show_tabs = gtk_check_button_new_with_label(_("Always show the tab bar")); gtk_widget_set_name(check_playlist_always_show_tabs, "check_on_notebook"); if (options.playlist_always_show_tabs) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_playlist_always_show_tabs), TRUE); } gtk_box_pack_start(GTK_BOX(vbox_pl), check_playlist_always_show_tabs, FALSE, TRUE, 0); check_show_close_button_in_tab = gtk_check_button_new_with_label(_("Show close button in tab")); gtk_widget_set_name(check_show_close_button_in_tab, "check_on_notebook"); if (options.playlist_show_close_button_in_tab) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_show_close_button_in_tab), TRUE); } gtk_box_pack_start(GTK_BOX(vbox_pl), check_show_close_button_in_tab, FALSE, TRUE, 0); check_album_shuffle_mode = gtk_check_button_new_with_label(_("When shuffling, records added in Album mode " "are played in order")); gtk_widget_set_name(check_album_shuffle_mode, "check_on_notebook"); if (options.album_shuffle_mode) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_album_shuffle_mode), TRUE); } gtk_box_pack_start(GTK_BOX(vbox_pl), check_album_shuffle_mode, FALSE, TRUE, 0); check_enable_playlist_statusbar = gtk_check_button_new_with_label(_("Enable statusbar")); gtk_widget_set_name(check_enable_playlist_statusbar, "check_on_notebook"); if (options.enable_playlist_statusbar_shadow) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_enable_playlist_statusbar), TRUE); } g_signal_connect(G_OBJECT(check_enable_playlist_statusbar), "toggled", G_CALLBACK(restart_active), _("Enable statusbar in playlist")); gtk_box_pack_start(GTK_BOX(vbox_pl), check_enable_playlist_statusbar, FALSE, TRUE, 0); check_pl_statusbar_show_size = gtk_check_button_new_with_label(_("Show soundfile size in statusbar")); gtk_widget_set_name(check_pl_statusbar_show_size, "check_on_notebook"); if (options.pl_statusbar_show_size) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_pl_statusbar_show_size), TRUE); } gtk_box_pack_start(GTK_BOX(vbox_pl), check_pl_statusbar_show_size, FALSE, TRUE, 0); check_show_rva_in_playlist = gtk_check_button_new_with_label(_("Show RVA values")); gtk_widget_set_name(check_show_rva_in_playlist, "check_on_notebook"); if (options.show_rva_in_playlist) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_show_rva_in_playlist), TRUE); } gtk_box_pack_start(GTK_BOX(vbox_pl), check_show_rva_in_playlist, FALSE, TRUE, 0); check_show_length_in_playlist = gtk_check_button_new_with_label(_("Show track lengths")); gtk_widget_set_name(check_show_length_in_playlist, "check_on_notebook"); if (options.show_length_in_playlist) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_show_length_in_playlist), TRUE); } gtk_box_pack_start(GTK_BOX(vbox_pl), check_show_length_in_playlist, FALSE, TRUE, 0); check_show_active_track_name_in_bold = gtk_check_button_new_with_label(_("Show active track name in bold")); gtk_widget_set_name(check_show_active_track_name_in_bold, "check_on_notebook"); track_name_in_bold_shadow = options.show_active_track_name_in_bold; if (options.show_active_track_name_in_bold) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_show_active_track_name_in_bold), TRUE); } gtk_box_pack_start(GTK_BOX(vbox_pl), check_show_active_track_name_in_bold, FALSE, TRUE, 0); check_auto_roll_to_active_track = gtk_check_button_new_with_label(_("Automatically roll to active track")); gtk_widget_set_name(check_auto_roll_to_active_track, "check_on_notebook"); if (options.auto_roll_to_active_track) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_auto_roll_to_active_track), TRUE); } gtk_box_pack_start(GTK_BOX(vbox_pl), check_auto_roll_to_active_track, FALSE, TRUE, 0); check_enable_pl_rules_hint = gtk_check_button_new_with_label(_("Enable rules hint")); gtk_widget_set_name(check_enable_pl_rules_hint, "check_on_notebook"); if (options.enable_pl_rules_hint) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_enable_pl_rules_hint), TRUE); } gtk_box_pack_start(GTK_BOX(vbox_pl), check_enable_pl_rules_hint, FALSE, TRUE, 0); frame_plistcol = gtk_frame_new(_("Playlist column order")); gtk_box_pack_start(GTK_BOX(vbox_pl), frame_plistcol, FALSE, TRUE, 5); vbox_plistcol = gtk_vbox_new(FALSE, 0); gtk_container_set_border_width(GTK_CONTAINER(vbox_plistcol), 8); gtk_container_add(GTK_CONTAINER(frame_plistcol), vbox_plistcol); label_plistcol = gtk_label_new(_("Drag and drop entries in the list below \n" "to set the column order in the Playlist.")); gtk_box_pack_start(GTK_BOX(vbox_plistcol), label_plistcol, FALSE, TRUE, 5); plistcol_store = gtk_list_store_new(2, G_TYPE_STRING, /* Column name */ G_TYPE_INT); /* Column index */ plistcol_list = gtk_tree_view_new_with_model(GTK_TREE_MODEL(plistcol_store)); gtk_tree_view_set_enable_search(GTK_TREE_VIEW(plistcol_list), FALSE); renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes(_("Column"), renderer, "text", 0, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(plistcol_list), column); gtk_tree_view_set_reorderable(GTK_TREE_VIEW(plistcol_list), TRUE); viewport = gtk_viewport_new(NULL, NULL); gtk_box_pack_start(GTK_BOX(vbox_plistcol), viewport, TRUE, TRUE, 5); gtk_container_add(GTK_CONTAINER(viewport), plistcol_list); for (i = 0; i < 3; i++) { switch (options.plcol_idx[i]) { case 0: gtk_list_store_append(plistcol_store, &iter); gtk_list_store_set(plistcol_store, &iter, 0, _("Track titles"), 1, 0, -1); break; case 1: gtk_list_store_append(plistcol_store, &iter); gtk_list_store_set(plistcol_store, &iter, 0, _("RVA values"), 1, 1, -1); break; case 2: gtk_list_store_append(plistcol_store, &iter); gtk_list_store_set(plistcol_store, &iter, 0, _("Track lengths"), 1, 2, -1); break; } } /* "Music Store" notebook page */ vbox_ms = gtk_vbox_new(FALSE, 3); gtk_container_set_border_width(GTK_CONTAINER(vbox_ms), 8); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox_ms, create_notebook_tab(_("Music Store"), "music_store.png")); check_hide_comment_pane = gtk_check_button_new_with_label(_("Hide comment pane")); gtk_widget_set_name(check_hide_comment_pane, "check_on_notebook"); if (options.hide_comment_pane_shadow) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_hide_comment_pane), TRUE); } gtk_box_pack_start(GTK_BOX(vbox_ms), check_hide_comment_pane, FALSE, FALSE, 0); g_signal_connect (G_OBJECT (check_hide_comment_pane), "toggled", G_CALLBACK (restart_active), _("Hide the Music Store comment pane")); check_enable_mstore_toolbar = gtk_check_button_new_with_label(_("Enable toolbar")); gtk_widget_set_name(check_enable_mstore_toolbar, "check_on_notebook"); if (options.enable_mstore_toolbar_shadow) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_enable_mstore_toolbar), TRUE); } g_signal_connect(G_OBJECT(check_enable_mstore_toolbar), "toggled", G_CALLBACK(restart_active), _("Enable toolbar in Music Store")); gtk_box_pack_start(GTK_BOX(vbox_ms), check_enable_mstore_toolbar, FALSE, TRUE, 0); check_enable_mstore_statusbar = gtk_check_button_new_with_label(_("Enable statusbar")); gtk_widget_set_name(check_enable_mstore_statusbar, "check_on_notebook"); if (options.enable_mstore_statusbar_shadow) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_enable_mstore_statusbar), TRUE); } g_signal_connect(G_OBJECT(check_enable_mstore_statusbar), "toggled", G_CALLBACK(restart_active), _("Enable statusbar in Music Store")); gtk_box_pack_start(GTK_BOX(vbox_ms), check_enable_mstore_statusbar, FALSE, TRUE, 0); check_ms_statusbar_show_size = gtk_check_button_new_with_label(_("Show soundfile size in statusbar")); gtk_widget_set_name(check_ms_statusbar_show_size, "check_on_notebook"); if (options.ms_statusbar_show_size) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_ms_statusbar_show_size), TRUE); } gtk_box_pack_start(GTK_BOX(vbox_ms), check_ms_statusbar_show_size, FALSE, TRUE, 0); check_expand_stores = gtk_check_button_new_with_label(_("Expand Stores on startup")); gtk_widget_set_name(check_expand_stores, "check_on_notebook"); if (options.autoexpand_stores) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_expand_stores), TRUE); } gtk_box_pack_start(GTK_BOX(vbox_ms), check_expand_stores, FALSE, FALSE, 0); check_enable_ms_rules_hint = gtk_check_button_new_with_label(_("Enable rules hint")); gtk_widget_set_name(check_enable_ms_rules_hint, "check_on_notebook"); if (options.enable_ms_rules_hint) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_enable_ms_rules_hint), TRUE); } gtk_box_pack_start(GTK_BOX(vbox_ms), check_enable_ms_rules_hint, FALSE, TRUE, 0); check_enable_ms_tree_icons = gtk_check_button_new_with_label(_("Enable tree node icons")); gtk_widget_set_name(check_enable_ms_tree_icons, "check_on_notebook"); if (options.enable_ms_tree_icons_shadow) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_enable_ms_tree_icons), TRUE); } g_signal_connect (G_OBJECT (check_enable_ms_tree_icons), "toggled", G_CALLBACK (restart_active), _("Enable Music Store tree node icons")); gtk_box_pack_start(GTK_BOX(vbox_ms), check_enable_ms_tree_icons, FALSE, TRUE, 0); check_ms_confirm_removal = gtk_check_button_new_with_label(_("Ask for confirmation when removing items")); gtk_widget_set_name(check_ms_confirm_removal, "check_on_notebook"); if (options.ms_confirm_removal) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_ms_confirm_removal), TRUE); } gtk_box_pack_start(GTK_BOX(vbox_ms), check_ms_confirm_removal, FALSE, FALSE, 0); frame_ms_pathlist = gtk_frame_new(_("Paths to Music Store databases")); gtk_box_pack_start(GTK_BOX(vbox_ms), frame_ms_pathlist, FALSE, TRUE, 5); vbox_ms_pathlist = gtk_vbox_new(FALSE, 0); gtk_container_set_border_width(GTK_CONTAINER(vbox_ms_pathlist), 8); gtk_container_add(GTK_CONTAINER(frame_ms_pathlist), vbox_ms_pathlist); ms_pathlist_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(ms_pathlist_store)); ms_pathlist_select = gtk_tree_view_get_selection(GTK_TREE_VIEW(ms_pathlist_view)); renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes(_("Path"), renderer, "text", 1, NULL); gtk_tree_view_column_set_resizable(GTK_TREE_VIEW_COLUMN(column), TRUE); gtk_tree_view_append_column(GTK_TREE_VIEW(ms_pathlist_view), column); renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes(_("Access"), renderer, "text", 2, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(ms_pathlist_view), column); gtk_widget_set_size_request(ms_pathlist_view, -1, 100); gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(ms_pathlist_view), TRUE); gtk_tree_view_set_reorderable(GTK_TREE_VIEW(ms_pathlist_view), TRUE); viewport = gtk_viewport_new(NULL, NULL); gtk_box_pack_start(GTK_BOX(vbox_ms_pathlist), viewport, FALSE, TRUE, 5); scrolled_win = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_win), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_container_add(GTK_CONTAINER(viewport), scrolled_win); gtk_container_add(GTK_CONTAINER(scrolled_win), ms_pathlist_view); hbox_ms_pathlist = gtk_hbox_new(FALSE, FALSE); gtk_box_pack_start(GTK_BOX(vbox_ms_pathlist), hbox_ms_pathlist, FALSE, FALSE, 0); entry_ms_pathlist = gtk_entry_new(); gtk_box_pack_start(GTK_BOX(hbox_ms_pathlist), entry_ms_pathlist, TRUE, TRUE, 2); browse_ms_pathlist = gui_stock_label_button(_("Browse"), GTK_STOCK_OPEN); gtk_container_set_border_width(GTK_CONTAINER(browse_ms_pathlist), 2); g_signal_connect (G_OBJECT(browse_ms_pathlist), "clicked", G_CALLBACK(browse_ms_pathlist_clicked), (gpointer)entry_ms_pathlist); gtk_box_pack_end(GTK_BOX(hbox_ms_pathlist), browse_ms_pathlist, FALSE, FALSE, 0); hbox_ms_pathlist_2 = gtk_hbox_new(FALSE, FALSE); gtk_box_pack_start(GTK_BOX(vbox_ms_pathlist), hbox_ms_pathlist_2, FALSE, FALSE, 0); help_pathlist = gtk_button_new_from_stock (GTK_STOCK_HELP); gtk_container_set_border_width(GTK_CONTAINER(help_pathlist), 2); g_signal_connect(help_pathlist, "clicked", G_CALLBACK(display_pathlist_help), NULL); gtk_box_pack_start(GTK_BOX(hbox_ms_pathlist_2), help_pathlist, FALSE, FALSE, 0); refresh_ms_pathlist = gui_stock_label_button(_("Refresh"), GTK_STOCK_REFRESH); gtk_container_set_border_width(GTK_CONTAINER(refresh_ms_pathlist), 2); g_signal_connect (G_OBJECT(refresh_ms_pathlist), "clicked", G_CALLBACK(refresh_ms_pathlist_clicked), NULL); gtk_box_pack_end(GTK_BOX(hbox_ms_pathlist_2), refresh_ms_pathlist, FALSE, FALSE, 0); remove_ms_pathlist = gui_stock_label_button(_("Remove"), GTK_STOCK_REMOVE); gtk_container_set_border_width(GTK_CONTAINER(remove_ms_pathlist), 2); g_signal_connect (G_OBJECT(remove_ms_pathlist), "clicked", G_CALLBACK(remove_ms_pathlist_clicked), NULL); gtk_box_pack_end(GTK_BOX(hbox_ms_pathlist_2), remove_ms_pathlist, FALSE, FALSE, 0); add_ms_pathlist = gui_stock_label_button(_("Add"), GTK_STOCK_ADD); gtk_container_set_border_width(GTK_CONTAINER(add_ms_pathlist), 2); g_signal_connect (G_OBJECT(add_ms_pathlist), "clicked", G_CALLBACK(add_ms_pathlist_clicked), NULL); gtk_box_pack_end(GTK_BOX(hbox_ms_pathlist_2), add_ms_pathlist, FALSE, FALSE, 0); /* "DSP" notebook page */ vbox_dsp = gtk_vbox_new(FALSE, 3); gtk_container_set_border_width(GTK_CONTAINER(vbox_dsp), 8); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox_dsp, create_notebook_tab(_("DSP"), "dsp.png")); frame_ladspa = gtk_frame_new(_("LADSPA plugin processing")); gtk_box_pack_start(GTK_BOX(vbox_dsp), frame_ladspa, FALSE, TRUE, 0); vbox_ladspa = gtk_vbox_new(FALSE, 3); gtk_container_set_border_width(GTK_CONTAINER(vbox_ladspa), 10); gtk_container_add(GTK_CONTAINER(frame_ladspa), vbox_ladspa); #ifdef HAVE_LADSPA combo_ladspa = gtk_combo_box_new_text (); gtk_box_pack_start(GTK_BOX(vbox_ladspa), combo_ladspa, TRUE, TRUE, 0); gtk_combo_box_append_text (GTK_COMBO_BOX (combo_ladspa), _("Pre Fader (before Volume & Balance)")); gtk_combo_box_append_text (GTK_COMBO_BOX (combo_ladspa), _("Post Fader (after Volume & Balance)")); status = options.ladspa_is_postfader; gtk_combo_box_set_active (GTK_COMBO_BOX (combo_ladspa), status); g_signal_connect(combo_ladspa, "changed", G_CALLBACK(changed_ladspa_prepost), NULL); #else { GtkWidget * label = gtk_label_new(_("Aqualung is compiled without LADSPA plugin support.\n" "See the About box and the documentation for details.")); gtk_box_pack_start(GTK_BOX(vbox_ladspa), label, FALSE, TRUE, 5); } #endif /* HAVE_LADSPA */ frame_src = gtk_frame_new(_("Sample Rate Converter type")); gtk_box_pack_start(GTK_BOX(vbox_dsp), frame_src, FALSE, TRUE, 5); vbox_src = gtk_vbox_new(FALSE, 3); gtk_container_set_border_width(GTK_CONTAINER(vbox_src), 10); gtk_container_add(GTK_CONTAINER(frame_src), vbox_src); label_src = gtk_label_new(""); #ifdef HAVE_SRC combo_src = gtk_combo_box_new_text (); gtk_box_pack_start(GTK_BOX(vbox_src), combo_src, TRUE, TRUE, 0); { int i = 0; while (src_get_name(i)) { gtk_combo_box_append_text (GTK_COMBO_BOX (combo_src), src_get_name(i)); ++i; } } gtk_combo_box_set_active (GTK_COMBO_BOX (combo_src), options.src_type); g_signal_connect(combo_src, "changed", G_CALLBACK(changed_src_type), NULL); gtk_label_set_text(GTK_LABEL(label_src), src_get_description(options.src_type)); #else gtk_label_set_text(GTK_LABEL(label_src), _("Aqualung is compiled without Sample Rate Converter support.\n" "See the About box and the documentation for details.")); #endif /* HAVE_SRC */ gtk_box_pack_start(GTK_BOX(vbox_src), label_src, TRUE, TRUE, 0); /* "Playback RVA" notebook page */ vbox_rva = gtk_vbox_new(FALSE, 3); gtk_container_set_border_width(GTK_CONTAINER(vbox_rva), 10); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox_rva, create_notebook_tab(_("Playback RVA"), "rva.png")); check_rva_is_enabled = gtk_check_button_new_with_label(_("Enable playback RVA")); gtk_widget_set_name(check_rva_is_enabled, "check_on_notebook"); if (options.rva_is_enabled) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_rva_is_enabled), TRUE); } rva_is_enabled_shadow = options.rva_is_enabled; g_signal_connect(G_OBJECT(check_rva_is_enabled), "toggled", G_CALLBACK(check_rva_is_enabled_toggled), NULL); gtk_box_pack_start(GTK_BOX(vbox_rva), check_rva_is_enabled, FALSE, TRUE, 0); table_rva = gtk_table_new(8, 2, FALSE); gtk_box_pack_start(GTK_BOX(vbox_rva), table_rva, TRUE, TRUE, 5); rva_viewport = gtk_viewport_new(NULL, NULL); gtk_widget_set_size_request(rva_viewport, 244, 244); gtk_table_attach(GTK_TABLE(table_rva), rva_viewport, 0, 2, 0, 1, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 5, 2); rva_drawing_area = gtk_drawing_area_new(); gtk_widget_set_size_request(GTK_WIDGET(rva_drawing_area), 240, 240); gtk_container_add(GTK_CONTAINER(rva_viewport), rva_drawing_area); g_signal_connect(G_OBJECT(rva_drawing_area), "configure_event", G_CALLBACK(rva_configure_event), NULL); g_signal_connect(G_OBJECT(rva_drawing_area), "expose_event", G_CALLBACK(rva_expose_event), NULL); hbox = gtk_hbox_new(FALSE, 0); label_listening_env = gtk_label_new(_("Listening environment:")); gtk_box_pack_start(GTK_BOX(hbox), label_listening_env, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(table_rva), hbox, 0, 1, 1, 2, GTK_FILL, GTK_FILL, 5, 2); combo_listening_env = gtk_combo_box_new_text (); gtk_table_attach(GTK_TABLE(table_rva), combo_listening_env, 1, 2, 1, 2, GTK_FILL | GTK_EXPAND, GTK_FILL, 5, 2); gtk_combo_box_append_text (GTK_COMBO_BOX (combo_listening_env), _("Audiophile")); gtk_combo_box_append_text (GTK_COMBO_BOX (combo_listening_env), _("Living room")); gtk_combo_box_append_text (GTK_COMBO_BOX (combo_listening_env), _("Office")); gtk_combo_box_append_text (GTK_COMBO_BOX (combo_listening_env), _("Noisy workshop")); rva_env_shadow = options.rva_env; gtk_combo_box_set_active (GTK_COMBO_BOX (combo_listening_env), options.rva_env); g_signal_connect(combo_listening_env, "changed", G_CALLBACK(changed_listening_env), NULL); hbox = gtk_hbox_new(FALSE, 0); label_refvol = gtk_label_new(_("Reference volume [dBFS] :")); gtk_box_pack_start(GTK_BOX(hbox), label_refvol, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(table_rva), hbox, 0, 1, 2, 3, GTK_FILL, GTK_FILL, 5, 2); rva_refvol_shadow = options.rva_refvol; adj_refvol = gtk_adjustment_new(options.rva_refvol, -24.0f, 0.0f, 0.1f, 1.0f, 0.0f); spin_refvol = gtk_spin_button_new(GTK_ADJUSTMENT(adj_refvol), 0.1, 1); gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(spin_refvol), TRUE); gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(spin_refvol), FALSE); g_signal_connect(G_OBJECT(adj_refvol), "value_changed", G_CALLBACK(refvol_changed), NULL); gtk_table_attach(GTK_TABLE(table_rva), spin_refvol, 1, 2, 2, 3, GTK_FILL, GTK_FILL, 5, 2); hbox = gtk_hbox_new(FALSE, 0); label_steepness = gtk_label_new(_("Steepness [dB/dB] :")); gtk_box_pack_start(GTK_BOX(hbox), label_steepness, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(table_rva), hbox, 0, 1, 3, 4, GTK_FILL, GTK_FILL, 5, 2); rva_steepness_shadow = options.rva_steepness; adj_steepness = gtk_adjustment_new(options.rva_steepness, 0.0f, 1.0f, 0.01f, 0.1f, 0.0f); spin_steepness = gtk_spin_button_new(GTK_ADJUSTMENT(adj_steepness), 0.02, 2); gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(spin_steepness), TRUE); gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(spin_steepness), FALSE); g_signal_connect(G_OBJECT(adj_steepness), "value_changed", G_CALLBACK(steepness_changed), NULL); gtk_table_attach(GTK_TABLE(table_rva), spin_steepness, 1, 2, 3, 4, GTK_FILL, GTK_FILL, 5, 2); hbox = gtk_hbox_new(FALSE, 0); label_defvol = gtk_label_new(_("RVA for Unmeasured Files [dB] :")); gtk_box_pack_start(GTK_BOX(hbox), label_defvol, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(table_rva), hbox, 0, 1, 4, 5, GTK_FILL, GTK_FILL, 5, 2); rva_no_rva_voladj_shadow = options.rva_no_rva_voladj; adj_defvol = gtk_adjustment_new(options.rva_no_rva_voladj, -10.0f, 10.0f, 0.1f, 1.0f, 0.0f); spin_defvol = gtk_spin_button_new(GTK_ADJUSTMENT(adj_defvol), 0.1, 1); gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(spin_defvol), TRUE); gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(spin_defvol), FALSE); g_signal_connect(G_OBJECT(adj_defvol), "value_changed", G_CALLBACK(defvol_changed), NULL); gtk_table_attach(GTK_TABLE(table_rva), spin_defvol, 1, 2, 4, 5, GTK_FILL, GTK_FILL, 5, 2); check_rva_use_averaging = gtk_check_button_new_with_label(_("Apply averaged RVA to tracks of the same record")); gtk_widget_set_name(check_rva_use_averaging, "check_on_notebook"); if (options.rva_use_averaging) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_rva_use_averaging), TRUE); } rva_use_averaging_shadow = options.rva_use_averaging; g_signal_connect(G_OBJECT(check_rva_use_averaging), "toggled", G_CALLBACK(check_rva_use_averaging_toggled), NULL); gtk_table_attach(GTK_TABLE(table_rva), check_rva_use_averaging, 0, 2, 5, 6, GTK_FILL, GTK_FILL, 5, 2); hbox = gtk_hbox_new(FALSE, 0); label_threshold = gtk_label_new(_("Drop statistical aberrations based on")); gtk_box_pack_start(GTK_BOX(hbox), label_threshold, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(table_rva), hbox, 0, 1, 6, 7, GTK_FILL, GTK_FILL, 5, 2); combo_threshold = gtk_combo_box_new_text (); gtk_table_attach(GTK_TABLE(table_rva), combo_threshold, 1, 2, 6, 7, GTK_FILL | GTK_EXPAND, GTK_FILL, 5, 2); /* xgettext:no-c-format */ gtk_combo_box_append_text(GTK_COMBO_BOX(combo_threshold), _("% of standard deviation")); gtk_combo_box_append_text(GTK_COMBO_BOX(combo_threshold), _("Linear threshold [dB]")); rva_use_linear_thresh_shadow = options.rva_use_linear_thresh; gtk_combo_box_set_active (GTK_COMBO_BOX (combo_threshold), options.rva_use_linear_thresh); g_signal_connect(combo_threshold, "changed", G_CALLBACK(changed_threshold), NULL); hbox = gtk_hbox_new(FALSE, 0); label_linthresh = gtk_label_new(_("Linear threshold [dB] :")); gtk_box_pack_start(GTK_BOX(hbox), label_linthresh, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(table_rva), hbox, 0, 1, 7, 8, GTK_FILL, GTK_FILL, 5, 2); rva_avg_linear_thresh_shadow = options.rva_avg_linear_thresh; adj_linthresh = gtk_adjustment_new(options.rva_avg_linear_thresh, 0.0f, 60.0f, 0.1f, 1.0f, 0.0f); spin_linthresh = gtk_spin_button_new(GTK_ADJUSTMENT(adj_linthresh), 0.1, 1); gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(spin_linthresh), TRUE); gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(spin_linthresh), FALSE); g_signal_connect(G_OBJECT(adj_linthresh), "value_changed", G_CALLBACK(linthresh_changed), NULL); gtk_table_attach(GTK_TABLE(table_rva), spin_linthresh, 1, 2, 7, 8, GTK_FILL, GTK_FILL, 5, 2); hbox = gtk_hbox_new(FALSE, 0); /* xgettext:no-c-format */ label_stdthresh = gtk_label_new(_("% of standard deviation :")); gtk_box_pack_start(GTK_BOX(hbox), label_stdthresh, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(table_rva), hbox, 0, 1, 8, 9, GTK_FILL, GTK_FILL, 5, 2); rva_avg_stddev_thresh_shadow = options.rva_avg_stddev_thresh; adj_stdthresh = gtk_adjustment_new(options.rva_avg_stddev_thresh * 100.0f, 0.0f, 500.0f, 1.0f, 10.0f, 0.0f); spin_stdthresh = gtk_spin_button_new(GTK_ADJUSTMENT(adj_stdthresh), 0.5, 0); gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(spin_stdthresh), TRUE); gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(spin_stdthresh), FALSE); g_signal_connect(G_OBJECT(adj_stdthresh), "value_changed", G_CALLBACK(stdthresh_changed), NULL); gtk_table_attach(GTK_TABLE(table_rva), spin_stdthresh, 1, 2, 8, 9, GTK_FILL, GTK_FILL, 5, 2); if (!rva_use_averaging_shadow) { gtk_widget_set_sensitive(combo_threshold, FALSE); gtk_widget_set_sensitive(label_threshold, FALSE); gtk_widget_set_sensitive(spin_linthresh, FALSE); gtk_widget_set_sensitive(label_linthresh, FALSE); gtk_widget_set_sensitive(spin_stdthresh, FALSE); gtk_widget_set_sensitive(label_stdthresh, FALSE); } if (!rva_is_enabled_shadow) { gtk_widget_set_sensitive(combo_listening_env, FALSE); gtk_widget_set_sensitive(label_listening_env, FALSE); gtk_widget_set_sensitive(spin_refvol, FALSE); gtk_widget_set_sensitive(label_refvol, FALSE); gtk_widget_set_sensitive(spin_steepness, FALSE); gtk_widget_set_sensitive(label_steepness, FALSE); gtk_widget_set_sensitive(check_rva_use_averaging, FALSE); gtk_widget_set_sensitive(combo_threshold, FALSE); gtk_widget_set_sensitive(label_threshold, FALSE); gtk_widget_set_sensitive(spin_linthresh, FALSE); gtk_widget_set_sensitive(label_linthresh, FALSE); gtk_widget_set_sensitive(spin_stdthresh, FALSE); gtk_widget_set_sensitive(label_stdthresh, FALSE); gtk_widget_set_sensitive(spin_defvol, FALSE); gtk_widget_set_sensitive(label_defvol, FALSE); } /* "Metadata" notebook page */ vbox_meta = gtk_vbox_new(FALSE, 3); gtk_container_set_border_width(GTK_CONTAINER(vbox_meta), 8); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox_meta, create_notebook_tab(_("Metadata"), "metadata.png")); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox_meta), hbox, FALSE, TRUE, 5); label = gtk_label_new(_("ReplayGain tag to use (with fallback to the other): ")); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 3); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox_meta), hbox, FALSE, TRUE, 0); combo_replaygain = gtk_combo_box_new_text (); gtk_box_pack_start(GTK_BOX(hbox), combo_replaygain, FALSE, FALSE, 35); gtk_combo_box_append_text (GTK_COMBO_BOX (combo_replaygain), _("Replaygain_track_gain")); gtk_combo_box_append_text (GTK_COMBO_BOX (combo_replaygain), _("Replaygain_album_gain")); gtk_combo_box_set_active (GTK_COMBO_BOX (combo_replaygain), options.replaygain_tag_to_use); hbox_meta = gtk_hbox_new(FALSE, 5); gtk_box_pack_start(GTK_BOX(vbox_meta), hbox_meta, FALSE, TRUE, 8); frame_meta = gtk_frame_new(_("Adding files to Playlist")); gtk_box_pack_start(GTK_BOX(hbox_meta), frame_meta, TRUE, TRUE, 0); vbox_meta2 = gtk_vbox_new(FALSE, 0); gtk_container_add(GTK_CONTAINER(frame_meta), vbox_meta2); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox_meta2), hbox, FALSE, TRUE, 3); check_meta_use_basename_only = gtk_check_button_new_with_label(_("Use basename only instead of full path\n" "if no metadata is available.")); gtk_widget_set_name(check_meta_use_basename_only, "check_on_notebook"); if (options.meta_use_basename_only) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_meta_use_basename_only), TRUE); } gtk_box_pack_start(GTK_BOX(hbox), check_meta_use_basename_only, FALSE, TRUE, 35); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox_meta2), hbox, FALSE, TRUE, 3); check_meta_rm_extension = gtk_check_button_new_with_label(_("Remove file extension")); gtk_widget_set_name(check_meta_rm_extension, "check_on_notebook"); if (options.meta_rm_extension) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_meta_rm_extension), TRUE); } gtk_box_pack_start(GTK_BOX(hbox), check_meta_rm_extension, FALSE, TRUE, 35); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox_meta2), hbox, FALSE, TRUE, 3); check_meta_us_to_space = gtk_check_button_new_with_label(_("Convert underscore to space")); gtk_widget_set_name(check_meta_us_to_space, "check_on_notebook"); if (options.meta_us_to_space) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_meta_us_to_space), TRUE); } gtk_box_pack_start(GTK_BOX(hbox), check_meta_us_to_space, FALSE, TRUE, 35); hbox_meta = gtk_hbox_new(FALSE, 5); gtk_box_pack_start(GTK_BOX(vbox_meta), hbox_meta, FALSE, TRUE, 8); frame_meta = gtk_frame_new(_("Metadata editor (File info dialog)")); gtk_box_pack_start(GTK_BOX(hbox_meta), frame_meta, TRUE, TRUE, 0); vbox_meta2 = gtk_vbox_new(FALSE, 0); gtk_container_add(GTK_CONTAINER(frame_meta), vbox_meta2); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox_meta2), hbox, FALSE, TRUE, 3); check_metaedit_auto_clone = gtk_check_button_new_with_label(_("When adding new frames, " "try to set their contents\nfrom another tag's equivalent frame.")); gtk_widget_set_name(check_metaedit_auto_clone, "check_on_notebook"); if (options.metaedit_auto_clone) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_metaedit_auto_clone), TRUE); } gtk_box_pack_start(GTK_BOX(hbox), check_metaedit_auto_clone, FALSE, TRUE, 35); hbox_meta = gtk_hbox_new(FALSE, 5); gtk_box_pack_start(GTK_BOX(vbox_meta), hbox_meta, FALSE, TRUE, 0); frame_meta = gtk_frame_new(_("Batch update & encode (mass tagger, CD ripper, file export)")); gtk_box_pack_start(GTK_BOX(hbox_meta), frame_meta, TRUE, TRUE, 0); vbox_meta2 = gtk_vbox_new(FALSE, 0); gtk_container_add(GTK_CONTAINER(frame_meta), vbox_meta2); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox_meta2), hbox, FALSE, TRUE, 5); label = gtk_label_new(_("Tags to add when creating or updating MPEG audio files:")); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 3); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox_meta2), hbox, FALSE, TRUE, 0); check_batch_mpeg_add_id3v1 = gtk_check_button_new_with_label(_("ID3v1")); gtk_widget_set_name(check_batch_mpeg_add_id3v1, "check_on_notebook"); if (options.batch_mpeg_add_id3v1) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_batch_mpeg_add_id3v1), TRUE); } gtk_box_pack_start(GTK_BOX(hbox), check_batch_mpeg_add_id3v1, FALSE, TRUE, 35); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox_meta2), hbox, FALSE, TRUE, 0); check_batch_mpeg_add_id3v2 = gtk_check_button_new_with_label(_("ID3v2")); gtk_widget_set_name(check_batch_mpeg_add_id3v2, "check_on_notebook"); if (options.batch_mpeg_add_id3v2) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_batch_mpeg_add_id3v2), TRUE); } gtk_box_pack_start(GTK_BOX(hbox), check_batch_mpeg_add_id3v2, FALSE, TRUE, 35); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox_meta2), hbox, FALSE, TRUE, 0); check_batch_mpeg_add_ape = gtk_check_button_new_with_label(_("APE")); gtk_widget_set_name(check_batch_mpeg_add_ape, "check_on_notebook"); if (options.batch_mpeg_add_ape) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_batch_mpeg_add_ape), TRUE); } gtk_box_pack_start(GTK_BOX(hbox), check_batch_mpeg_add_ape, FALSE, TRUE, 35); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox_meta2), hbox, FALSE, TRUE, 5); label = gtk_label_new(_("Note: pre-existing tags will be updated even though they\n" "might not be checked here.")); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 3); /* CDDA notebook page */ #ifdef HAVE_CDDA table_cdda = gtk_table_new(5, 3, FALSE); gtk_container_set_border_width(GTK_CONTAINER(table_cdda), 8); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), table_cdda, create_notebook_tab(_("CD Audio"), "cdda.png")); label = gtk_label_new(_("CD drive speed:")); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(table_cdda), hbox, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 5, 3); cdda_drive_speed_spinner = gtk_spin_button_new_with_range(1, 99, 1); gtk_spin_button_set_value(GTK_SPIN_BUTTON(cdda_drive_speed_spinner), options.cdda_drive_speed); gtk_table_attach(GTK_TABLE(table_cdda), cdda_drive_speed_spinner, 1, 2, 0, 1, GTK_FILL | GTK_EXPAND, GTK_FILL, 5, 3); help_btn_cdda_drive_speed = gtk_button_new_from_stock(GTK_STOCK_HELP); g_signal_connect(help_btn_cdda_drive_speed, "clicked", G_CALLBACK(display_cdda_drive_speed_help), NULL); gtk_table_attach(GTK_TABLE(table_cdda), help_btn_cdda_drive_speed, 2, 3, 0, 1, GTK_FILL, GTK_FILL, 5, 3); frame_cdda = gtk_frame_new(_("Paranoia error correction")); gtk_table_attach(GTK_TABLE(table_cdda), frame_cdda, 0, 3, 1, 2, GTK_FILL | GTK_EXPAND, GTK_FILL, 5, 3); vbox_cdda = gtk_vbox_new(FALSE, 3); gtk_container_set_border_width(GTK_CONTAINER(vbox_cdda), 8); gtk_container_add(GTK_CONTAINER(frame_cdda), vbox_cdda); check_cdda_mode_overlap = gtk_check_button_new_with_label(_("Perform overlapped reads")); gtk_widget_set_name(check_cdda_mode_overlap, "check_on_notebook"); gtk_box_pack_start(GTK_BOX(vbox_cdda), check_cdda_mode_overlap, FALSE, FALSE, 0); check_cdda_mode_verify = gtk_check_button_new_with_label(_("Verify data integrity")); gtk_widget_set_name(check_cdda_mode_verify, "check_on_notebook"); gtk_box_pack_start(GTK_BOX(vbox_cdda), check_cdda_mode_verify, FALSE, FALSE, 0); check_cdda_mode_neverskip = gtk_check_button_new_with_label(_("Unlimited retry on failed reads (never skip)")); gtk_widget_set_name(check_cdda_mode_neverskip, "check_on_notebook"); if (options.cdda_paranoia_mode & PARANOIA_MODE_NEVERSKIP) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_cdda_mode_neverskip), TRUE); } gtk_box_pack_start(GTK_BOX(vbox_cdda), check_cdda_mode_neverskip, FALSE, FALSE, 0); g_signal_connect(check_cdda_mode_neverskip, "toggled", G_CALLBACK(cdda_toggled), NULL); hbox_cdda = gtk_hbox_new(FALSE, 3); gtk_box_pack_start(GTK_BOX(vbox_cdda), hbox_cdda, FALSE, FALSE, 0); label_cdda_maxretries = gtk_label_new(_("\tMaximum number of retries:")); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), label_cdda_maxretries, FALSE, FALSE, 5); gtk_box_pack_start(GTK_BOX(hbox_cdda), hbox, FALSE, FALSE, 0); cdda_paranoia_maxretries_spinner = gtk_spin_button_new_with_range(1, 50, 1); gtk_spin_button_set_value(GTK_SPIN_BUTTON(cdda_paranoia_maxretries_spinner), options.cdda_paranoia_maxretries); gtk_box_pack_start(GTK_BOX(hbox_cdda), cdda_paranoia_maxretries_spinner, FALSE, FALSE, 5); check_cdda_force_drive_rescan = gtk_check_button_new_with_label(_("Force TOC re-read on every drive scan")); gtk_widget_set_name(check_cdda_force_drive_rescan, "check_on_notebook"); gtk_table_attach(GTK_TABLE(table_cdda), check_cdda_force_drive_rescan, 0, 2, 2, 3, GTK_FILL | GTK_EXPAND, GTK_FILL, 5, 3); help_btn_cdda_force_drive_rescan = gtk_button_new_from_stock(GTK_STOCK_HELP); g_signal_connect(help_btn_cdda_force_drive_rescan, "clicked", G_CALLBACK(display_cdda_force_drive_rescan_help), NULL); gtk_table_attach(GTK_TABLE(table_cdda), help_btn_cdda_force_drive_rescan, 2, 3, 2, 3, GTK_FILL, GTK_FILL, 5, 3); check_cdda_add_to_playlist = gtk_check_button_new_with_label(_("Automatically add CDs to Playlist")); gtk_widget_set_name(check_cdda_add_to_playlist, "check_on_notebook"); gtk_table_attach(GTK_TABLE(table_cdda), check_cdda_add_to_playlist, 0, 3, 3, 4, GTK_FILL | GTK_EXPAND, GTK_FILL, 5, 3); check_cdda_remove_from_playlist = gtk_check_button_new_with_label(_("Automatically remove CDs from Playlist")); gtk_widget_set_name(check_cdda_remove_from_playlist, "check_on_notebook"); gtk_table_attach(GTK_TABLE(table_cdda), check_cdda_remove_from_playlist, 0, 3, 4, 5, GTK_FILL | GTK_EXPAND, GTK_FILL, 5, 3); if (options.cdda_force_drive_rescan) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_cdda_force_drive_rescan), TRUE); } if (options.cdda_paranoia_mode & PARANOIA_MODE_OVERLAP) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_cdda_mode_overlap), TRUE); } if (options.cdda_paranoia_mode & PARANOIA_MODE_VERIFY) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_cdda_mode_verify), TRUE); } if (options.cdda_paranoia_mode & PARANOIA_MODE_NEVERSKIP) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_cdda_mode_neverskip), TRUE); gtk_widget_set_sensitive(cdda_paranoia_maxretries_spinner, FALSE); gtk_widget_set_sensitive(label_cdda_maxretries, FALSE); } if (options.cdda_add_to_playlist) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_cdda_add_to_playlist), TRUE); } if (options.cdda_remove_from_playlist) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_cdda_remove_from_playlist), TRUE); } #endif /* HAVE_CDDA */ /* CDDB notebook page */ #ifdef HAVE_CDDB table_cddb = gtk_table_new(8, 2, FALSE); gtk_container_set_border_width(GTK_CONTAINER(table_cddb), 8); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), table_cddb, create_notebook_tab(_("CDDB"), "cddb.png")); label = gtk_label_new(_("CDDB server:")); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(table_cddb), hbox, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 5, 3); cddb_server_entry = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(cddb_server_entry), options.cddb_server); gtk_table_attach(GTK_TABLE(table_cddb), cddb_server_entry, 1, 2, 0, 1, GTK_FILL | GTK_EXPAND, GTK_FILL, 5, 3); label = gtk_label_new(_("Connection timeout [sec]:")); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(table_cddb), hbox, 0, 1, 1, 2, GTK_FILL, GTK_FILL, 5, 3); cddb_tout_spinner = gtk_spin_button_new_with_range(1, 60, 1); gtk_spin_button_set_value(GTK_SPIN_BUTTON(cddb_tout_spinner), options.cddb_timeout); gtk_table_attach(GTK_TABLE(table_cddb), cddb_tout_spinner, 1, 2, 1, 2, GTK_FILL | GTK_EXPAND, GTK_FILL, 5, 3); label = gtk_label_new(_("Email address for submission:")); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(table_cddb), hbox, 0, 1, 2, 3, GTK_FILL, GTK_FILL, 5, 3); cddb_email_entry = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(cddb_email_entry), options.cddb_email); gtk_table_attach(GTK_TABLE(table_cddb), cddb_email_entry, 1, 2, 2, 3, GTK_FILL | GTK_EXPAND, GTK_FILL, 5, 3); label = gtk_label_new(_("Local CDDB directory:")); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(table_cddb), hbox, 0, 1, 3, 4, GTK_FILL, GTK_FILL, 5, 3); cddb_local_entry = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(cddb_local_entry), options.cddb_local); gtk_table_attach(GTK_TABLE(table_cddb), cddb_local_entry, 1, 2, 3, 4, GTK_FILL | GTK_EXPAND, GTK_FILL, 5, 3); cddb_local_check = gtk_check_button_new_with_label(_("Use the local database only")); gtk_widget_set_name(cddb_local_check, "check_on_notebook"); gtk_table_attach(GTK_TABLE(table_cddb), cddb_local_check, 0, 2, 4, 5, GTK_FILL | GTK_EXPAND, GTK_FILL, 5, 3); if (options.cddb_cache_only) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cddb_local_check), TRUE); } else { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cddb_local_check), FALSE); } cddb_label_proto = gtk_label_new(_("Protocol for querying (direct connection only):")); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), cddb_label_proto, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(table_cddb), hbox, 0, 1, 5, 6, GTK_FILL, GTK_FILL, 5, 3); cddb_proto_combo = gtk_combo_box_new_text(); gtk_combo_box_append_text(GTK_COMBO_BOX(cddb_proto_combo), _("CDDBP (port 888)")); gtk_combo_box_append_text(GTK_COMBO_BOX(cddb_proto_combo), _("HTTP (port 80)")); if (options.cddb_use_http) { gtk_combo_box_set_active(GTK_COMBO_BOX(cddb_proto_combo), 1); } else { gtk_combo_box_set_active(GTK_COMBO_BOX(cddb_proto_combo), 0); } gtk_table_attach(GTK_TABLE(table_cddb), cddb_proto_combo, 1, 2, 5, 6, GTK_FILL | GTK_EXPAND, GTK_FILL, 5, 3); #endif /* HAVE_CDDB */ /* Internet notebook page */ vbox_inet = gtk_vbox_new(FALSE, 3); gtk_container_set_border_width(GTK_CONTAINER(vbox_inet), 8); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox_inet, create_notebook_tab(_("Internet"), "inet.png")); inet_radio_direct = gtk_radio_button_new_with_label(NULL, _("Direct connection to the Internet")); gtk_widget_set_name(inet_radio_direct, "check_on_notebook"); gtk_box_pack_start(GTK_BOX(vbox_inet), inet_radio_direct, FALSE, FALSE, 0); g_signal_connect(G_OBJECT(inet_radio_direct), "toggled", G_CALLBACK(inet_radio_direct_toggled), NULL); inet_radio_proxy = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(inet_radio_direct), _("Connect via HTTP proxy")); gtk_widget_set_name(inet_radio_proxy, "check_on_notebook"); gtk_box_pack_start(GTK_BOX(vbox_inet), inet_radio_proxy, FALSE, FALSE, 0); inet_frame = gtk_frame_new(_("Proxy settings")); gtk_box_pack_start(GTK_BOX(vbox_inet), inet_frame, FALSE, FALSE, 0); table_inet = gtk_table_new(2/*row*/, 4, FALSE); gtk_container_set_border_width(GTK_CONTAINER(table_inet), 8); gtk_container_add(GTK_CONTAINER(inet_frame), table_inet); inet_label_proxy = gtk_label_new(_("Proxy host:")); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), inet_label_proxy, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(table_inet), hbox, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 5, 3); inet_entry_proxy = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(inet_entry_proxy), options.inet_proxy); gtk_table_attach(GTK_TABLE(table_inet), inet_entry_proxy, 1, 2, 0, 1, GTK_FILL | GTK_EXPAND, GTK_FILL, 5, 3); inet_label_proxy_port = gtk_label_new(_("Port:")); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), inet_label_proxy_port, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(table_inet), hbox, 2, 3, 0, 1, GTK_FILL, GTK_FILL, 5, 3); inet_spinner_proxy_port = gtk_spin_button_new_with_range(0, 65535, 1); gtk_spin_button_set_value(GTK_SPIN_BUTTON(inet_spinner_proxy_port), options.inet_proxy_port); gtk_table_attach(GTK_TABLE(table_inet), inet_spinner_proxy_port, 3, 4, 0, 1, GTK_FILL, GTK_FILL, 5, 3); inet_label_noproxy_domains = gtk_label_new(_("No proxy for:")); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), inet_label_noproxy_domains, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(table_inet), hbox, 0, 1, 1, 2, GTK_FILL, GTK_FILL, 5, 3); inet_entry_noproxy_domains = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(inet_entry_noproxy_domains), options.inet_noproxy_domains); gtk_table_attach(GTK_TABLE(table_inet), inet_entry_noproxy_domains, 1, 3, 1, 2, GTK_FILL | GTK_EXPAND, GTK_FILL, 5, 3); inet_help_noproxy_domains = gtk_button_new_from_stock(GTK_STOCK_HELP); g_signal_connect(inet_help_noproxy_domains, "clicked", G_CALLBACK(display_inet_help_noproxy_domains), NULL); gtk_table_attach(GTK_TABLE(table_inet), inet_help_noproxy_domains, 3, 4, 1, 2, GTK_FILL, GTK_FILL, 5, 3); inet_hbox_timeout = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox_inet), inet_hbox_timeout, FALSE, FALSE, 5); inet_label_timeout = gtk_label_new(_("Timeout for socket I/O:")); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), inet_label_timeout, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(inet_hbox_timeout), hbox, FALSE, FALSE, 5); inet_spinner_timeout = gtk_spin_button_new_with_range(1, 300, 1); gtk_spin_button_set_value(GTK_SPIN_BUTTON(inet_spinner_timeout), options.inet_timeout); gtk_box_pack_start(GTK_BOX(inet_hbox_timeout), inet_spinner_timeout, FALSE, FALSE, 5); inet_label_timeout = gtk_label_new(_("seconds")); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), inet_label_timeout, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(inet_hbox_timeout), hbox, FALSE, FALSE, 5); if (options.inet_use_proxy) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(inet_radio_direct), FALSE); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(inet_radio_proxy), TRUE); } else { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(inet_radio_direct), TRUE); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(inet_radio_proxy), FALSE); gtk_widget_set_sensitive(inet_frame, FALSE); } /* Appearance notebook page */ override_shadow = options.override_skin_settings; vbox_appearance = gtk_vbox_new(FALSE, 3); gtk_container_set_border_width(GTK_CONTAINER(vbox_appearance), 8); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox_appearance, create_notebook_tab(_("Appearance"), "appearance.png")); check_disable_skin_support = gtk_check_button_new_with_label(_("Disable skin support")); gtk_widget_set_name(check_disable_skin_support, "check_on_notebook"); gtk_box_pack_start(GTK_BOX(vbox_appearance), check_disable_skin_support, FALSE, FALSE, 0); check_override_skin = gtk_check_button_new_with_label(_("Override skin settings")); gtk_widget_set_name(check_override_skin, "check_on_notebook"); if (options.override_skin_settings) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_override_skin), TRUE); } gtk_box_pack_start(GTK_BOX(vbox_appearance), check_override_skin, FALSE, FALSE, 0); g_signal_connect (G_OBJECT (check_override_skin), "toggled", G_CALLBACK (cb_toggle_override_skin), NULL); if (options.disable_skin_support_settings) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_disable_skin_support), TRUE); gtk_widget_set_sensitive(check_override_skin, FALSE); } g_signal_connect (G_OBJECT (check_disable_skin_support), "toggled", G_CALLBACK (cb_toggle_disable_skin_support), NULL); frame_fonts = gtk_frame_new(_("Fonts")); gtk_box_pack_start(GTK_BOX(vbox_appearance), frame_fonts, FALSE, TRUE, 5); table_fonts = gtk_table_new (7, 3, FALSE); gtk_widget_show (table_fonts); gtk_container_add(GTK_CONTAINER(frame_fonts), table_fonts); gtk_container_set_border_width(GTK_CONTAINER(table_fonts), 5); gtk_table_set_row_spacings (GTK_TABLE (table_fonts), 4); gtk_table_set_col_spacings (GTK_TABLE (table_fonts), 4); /* playlist font */ label = gtk_label_new(_("Playlist: ")); gtk_table_attach (GTK_TABLE (table_fonts), label, 0, 1, 0, 1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); entry_pl_font = gtk_entry_new(); GTK_WIDGET_UNSET_FLAGS(entry_pl_font, GTK_CAN_FOCUS); gtk_editable_set_editable(GTK_EDITABLE(entry_pl_font), FALSE); gtk_table_attach (GTK_TABLE (table_fonts), entry_pl_font, 1, 2, 0, 1, (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), (GtkAttachOptions) (0), 0, 0); if (strlen(options.playlist_font)) { gtk_entry_set_text(GTK_ENTRY(entry_pl_font), options.playlist_font); } else { gtk_entry_set_text(GTK_ENTRY(entry_pl_font), DEFAULT_FONT_NAME); strcpy(options.playlist_font, DEFAULT_FONT_NAME); } button_pl_font = gui_stock_label_button(_("Select"), GTK_STOCK_SELECT_FONT); g_signal_connect (G_OBJECT (button_pl_font), "clicked", G_CALLBACK (appearance_font_select), entry_pl_font); gtk_table_attach (GTK_TABLE (table_fonts), button_pl_font, 2, 3, 0, 1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); /* music store font */ label = gtk_label_new(_("Music Store: ")); gtk_table_attach (GTK_TABLE (table_fonts), label, 0, 1, 1, 2, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); entry_ms_font = gtk_entry_new(); GTK_WIDGET_UNSET_FLAGS(entry_ms_font, GTK_CAN_FOCUS); gtk_editable_set_editable(GTK_EDITABLE(entry_ms_font), FALSE); gtk_table_attach (GTK_TABLE (table_fonts), entry_ms_font, 1, 2, 1, 2, (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), (GtkAttachOptions) (0), 0, 0); if (strlen(options.browser_font)) { gtk_entry_set_text(GTK_ENTRY(entry_ms_font), options.browser_font); } else { gtk_entry_set_text(GTK_ENTRY(entry_ms_font), DEFAULT_FONT_NAME); strcpy(options.browser_font, DEFAULT_FONT_NAME); } button_ms_font = gui_stock_label_button(_("Select"), GTK_STOCK_SELECT_FONT); g_signal_connect (G_OBJECT (button_ms_font), "clicked", G_CALLBACK (appearance_font_select), entry_ms_font); gtk_table_attach (GTK_TABLE (table_fonts), button_ms_font, 2, 3, 1, 2, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); /* big timer font */ label = gtk_label_new(_("Big timer: ")); gtk_table_attach (GTK_TABLE (table_fonts), label, 0, 1, 2, 3, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); entry_bt_font = gtk_entry_new(); GTK_WIDGET_UNSET_FLAGS(entry_bt_font, GTK_CAN_FOCUS); gtk_editable_set_editable(GTK_EDITABLE(entry_bt_font), FALSE); gtk_table_attach (GTK_TABLE (table_fonts), entry_bt_font, 1, 2, 2, 3, (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), (GtkAttachOptions) (0), 0, 0); if (strlen(options.bigtimer_font)) { gtk_entry_set_text(GTK_ENTRY(entry_bt_font), options.bigtimer_font); } else { gtk_entry_set_text(GTK_ENTRY(entry_bt_font), DEFAULT_FONT_NAME); strcpy(options.bigtimer_font, DEFAULT_FONT_NAME); } button_bt_font = gui_stock_label_button(_("Select"), GTK_STOCK_SELECT_FONT); g_signal_connect (G_OBJECT (button_bt_font), "clicked", G_CALLBACK (appearance_font_select), entry_bt_font); gtk_table_attach (GTK_TABLE (table_fonts), button_bt_font, 2, 3, 2, 3, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); /* small timer font */ label = gtk_label_new(_("Small timers: ")); gtk_table_attach (GTK_TABLE (table_fonts), label, 0, 1, 3, 4, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); entry_st_font = gtk_entry_new(); GTK_WIDGET_UNSET_FLAGS(entry_st_font, GTK_CAN_FOCUS); gtk_editable_set_editable(GTK_EDITABLE(entry_st_font), FALSE); gtk_table_attach (GTK_TABLE (table_fonts), entry_st_font, 1, 2, 3, 4, (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), (GtkAttachOptions) (0), 0, 0); if (strlen(options.smalltimer_font)) { gtk_entry_set_text(GTK_ENTRY(entry_st_font), options.smalltimer_font); } else { gtk_entry_set_text(GTK_ENTRY(entry_st_font), DEFAULT_FONT_NAME); strcpy(options.smalltimer_font, DEFAULT_FONT_NAME); } button_st_font = gui_stock_label_button(_("Select"), GTK_STOCK_SELECT_FONT); g_signal_connect (G_OBJECT (button_st_font), "clicked", G_CALLBACK (appearance_font_select), entry_st_font); gtk_table_attach (GTK_TABLE (table_fonts), button_st_font, 2, 3, 3, 4, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); /* song title font */ label = gtk_label_new(_("Song title: ")); gtk_table_attach (GTK_TABLE (table_fonts), label, 0, 1, 4, 5, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); entry_songt_font = gtk_entry_new(); GTK_WIDGET_UNSET_FLAGS(entry_songt_font, GTK_CAN_FOCUS); gtk_editable_set_editable(GTK_EDITABLE(entry_songt_font), FALSE); gtk_table_attach (GTK_TABLE (table_fonts), entry_songt_font, 1, 2, 4, 5, (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), (GtkAttachOptions) (0), 0, 0); if (strlen(options.songtitle_font)) { gtk_entry_set_text(GTK_ENTRY(entry_songt_font), options.songtitle_font); } else { gtk_entry_set_text(GTK_ENTRY(entry_songt_font), DEFAULT_FONT_NAME); strcpy(options.songtitle_font, DEFAULT_FONT_NAME); } button_songt_font = gui_stock_label_button(_("Select"), GTK_STOCK_SELECT_FONT); g_signal_connect (G_OBJECT (button_songt_font), "clicked", G_CALLBACK (appearance_font_select), entry_songt_font); gtk_table_attach (GTK_TABLE (table_fonts), button_songt_font, 2, 3, 4, 5, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); /* song info font */ label = gtk_label_new(_("Song info: ")); gtk_table_attach (GTK_TABLE (table_fonts), label, 0, 1, 5, 6, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); entry_si_font = gtk_entry_new(); GTK_WIDGET_UNSET_FLAGS(entry_si_font, GTK_CAN_FOCUS); gtk_editable_set_editable(GTK_EDITABLE(entry_si_font), FALSE); gtk_table_attach (GTK_TABLE (table_fonts), entry_si_font, 1, 2, 5, 6, (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), (GtkAttachOptions) (0), 0, 0); if (strlen(options.songinfo_font)) { gtk_entry_set_text(GTK_ENTRY(entry_si_font), options.songinfo_font); } else { gtk_entry_set_text(GTK_ENTRY(entry_si_font), DEFAULT_FONT_NAME); strcpy(options.songinfo_font, DEFAULT_FONT_NAME); } button_si_font = gui_stock_label_button(_("Select"), GTK_STOCK_SELECT_FONT); g_signal_connect (G_OBJECT (button_si_font), "clicked", G_CALLBACK (appearance_font_select), entry_si_font); gtk_table_attach (GTK_TABLE (table_fonts), button_si_font, 2, 3, 5, 6, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); /* statusbar font */ label = gtk_label_new(_("Statusbar: ")); gtk_table_attach (GTK_TABLE (table_fonts), label, 0, 1, 6, 7, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); entry_sb_font = gtk_entry_new(); GTK_WIDGET_UNSET_FLAGS(entry_sb_font, GTK_CAN_FOCUS); gtk_editable_set_editable(GTK_EDITABLE(entry_sb_font), FALSE); gtk_table_attach (GTK_TABLE (table_fonts), entry_sb_font, 1, 2, 6, 7, (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), (GtkAttachOptions) (0), 0, 0); if (strlen(options.statusbar_font)) { gtk_entry_set_text(GTK_ENTRY(entry_sb_font), options.statusbar_font); } else { gtk_entry_set_text(GTK_ENTRY(entry_sb_font), DEFAULT_FONT_NAME); strcpy(options.statusbar_font, DEFAULT_FONT_NAME); } button_sb_font = gui_stock_label_button(_("Select"), GTK_STOCK_SELECT_FONT); g_signal_connect (G_OBJECT (button_sb_font), "clicked", G_CALLBACK (appearance_font_select), entry_sb_font); gtk_table_attach (GTK_TABLE (table_fonts), button_sb_font, 2, 3, 6, 7, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); /* colors */ frame_colors = gtk_frame_new(_("Colors")); gtk_box_pack_start(GTK_BOX(vbox_appearance), frame_colors, FALSE, TRUE, 5); vbox_colors = gtk_vbox_new(FALSE, 3); gtk_container_set_border_width(GTK_CONTAINER(vbox_colors), 5); gtk_container_add(GTK_CONTAINER(frame_colors), vbox_colors); /* song color */ hbox = gtk_hbox_new(FALSE, 5); gtk_box_pack_start(GTK_BOX(vbox_colors), hbox, FALSE, TRUE, 0); label = gtk_label_new(_("Song in playlist: ")); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5); gtk_size_group_add_widget(label_size, label); gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); hbox_s = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), hbox_s, TRUE, TRUE, 0); if (gdk_color_parse(options.song_color, &color) == FALSE) { color.red = playlist_color_indicator->style->fg[SELECTED].red; color.green = playlist_color_indicator->style->fg[SELECTED].green; color.blue = playlist_color_indicator->style->fg[SELECTED].blue; color.pixel = (gulong)((color.red & 0xff00)*256 + (color.green & 0xff00) + (color.blue & 0xff00)/256); } color_picker = gtk_color_button_new_with_color (&color); gtk_widget_set_size_request(GTK_WIDGET(color_picker), 60, -1); gtk_box_pack_start(GTK_BOX(hbox), color_picker, FALSE, TRUE, 0); g_signal_connect (G_OBJECT (color_picker), "color-set", G_CALLBACK (color_selected), (gpointer *) SONG_COLOR); /* active song color */ hbox = gtk_hbox_new(FALSE, 5); gtk_box_pack_start(GTK_BOX(vbox_colors), hbox, FALSE, TRUE, 0); label = gtk_label_new(_("Active song in playlist: ")); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5); gtk_size_group_add_widget(label_size, label); gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); hbox_s = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), hbox_s, TRUE, TRUE, 0); if (gdk_color_parse(options.activesong_color, &color) == FALSE) { color.red = playlist_color_indicator->style->fg[SELECTED].red; color.green = playlist_color_indicator->style->fg[SELECTED].green; color.blue = playlist_color_indicator->style->fg[SELECTED].blue; color.pixel = (gulong)((color.red & 0xff00)*256 + (color.green & 0xff00) + (color.blue & 0xff00)/256); } color_picker = gtk_color_button_new_with_color (&color); gtk_widget_set_size_request(GTK_WIDGET(color_picker), 60, -1); gtk_box_pack_start(GTK_BOX(hbox), color_picker, FALSE, TRUE, 0); g_signal_connect (G_OBJECT (color_picker), "color-set", G_CALLBACK (color_selected), (gpointer *) ACTIVE_SONG_COLOR); set_sensitive_part(); /* end of notebook */ gtk_widget_show_all(options_window); gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook), current_notebook_page); display: ret = aqualung_dialog_run(GTK_DIALOG(options_window)); current_notebook_page = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)); if (ret == GTK_RESPONSE_ACCEPT) { char buf[MAXLEN]; char * format = (char *)gtk_entry_get_text(GTK_ENTRY(entry_title)); if ((ret = make_string_va(buf, format, 'a', "a", 'r', "r", 't', "t", 0)) != 0) { make_string_strerror(ret, buf); message_dialog(_("Error in title format string"), options_window, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, NULL, buf); goto display; } options_window_accept(); gtk_widget_destroy(options_window); if (reskin_flag) { if (!options.disable_skin_support_settings) { apply_skin(options.skin); gtk_widget_show(conf__skin); } else { gtk_widget_hide(conf__skin); } } } else { gtk_widget_destroy(options_window); } #ifdef HAVE_SYSTRAY #if (GTK_CHECK_VERSION(2,15,0)) gtk_list_store_clear(systray_mouse_buttons_store); gtk_list_store_clear(systray_mouse_buttons_cmds_store); #endif /* HAVE_SYSTRAY */ #endif /* GTK_CHECK_VERSION */ } #define SAVE_STR(Var) \ xmlNewTextChild(root, NULL, (const xmlChar *) #Var, (xmlChar *) options.Var); #define SAVE_FONT(Font) \ snprintf(str, MAX_FONTNAME_LEN, "%s", options.Font); \ xmlNewTextChild(root, NULL, (const xmlChar *) #Font, (xmlChar *) str); #define SAVE_COLOR(Color) \ snprintf(str, MAX_COLORNAME_LEN, "%s", options.Color); \ xmlNewTextChild(root, NULL, (const xmlChar *) #Color, (xmlChar *) str); #define SAVE_INT(Var) \ snprintf(str, 31, "%d", options.Var); \ xmlNewTextChild(root, NULL, (const xmlChar *) #Var, (xmlChar *) str); #define SAVE_INT_ARRAY(Var, Idx) \ snprintf(str, 31, "%d", options.Var[Idx]); \ xmlNewTextChild(root, NULL, (const xmlChar *) #Var "_" #Idx, (xmlChar *) str); #define SAVE_INT_SH(Var) \ snprintf(str, 31, "%d", options.Var##_shadow); \ xmlNewTextChild(root, NULL, (const xmlChar *) #Var, (xmlChar *) str); #define SAVE_FLOAT(Var) \ snprintf(str, 31, "%f", options.Var); \ xmlNewTextChild(root, NULL, (const xmlChar *) #Var, (xmlChar *) str); void save_config(void) { xmlDocPtr doc; xmlNodePtr root; int c, d; FILE * fin; FILE * fout; char tmpname[MAXLEN]; char config_file[MAXLEN]; char str[MAXLEN]; GtkTreeIter iter; int i = 0; char * path; sprintf(config_file, "%s/config.xml", options.confdir); doc = xmlNewDoc((const xmlChar *) "1.0"); root = xmlNewNode(NULL, (const xmlChar *) "aqualung_config"); xmlDocSetRootElement(doc, root); SAVE_STR(audiodir); SAVE_STR(currdir); SAVE_STR(exportdir); SAVE_STR(plistdir); SAVE_STR(podcastdir); SAVE_STR(ripdir); SAVE_STR(storedir); SAVE_STR(default_param); SAVE_STR(title_format); SAVE_STR(skin); SAVE_INT(src_type); SAVE_INT(ladspa_is_postfader); SAVE_INT(auto_save_playlist); SAVE_INT(playlist_auto_save); SAVE_INT(playlist_auto_save_int); SAVE_INT(show_rva_in_playlist); SAVE_INT(pl_statusbar_show_size); SAVE_INT(ms_statusbar_show_size); SAVE_INT(show_length_in_playlist); SAVE_INT(show_active_track_name_in_bold); SAVE_INT(auto_roll_to_active_track); SAVE_INT(enable_pl_rules_hint); SAVE_INT(enable_ms_rules_hint); SAVE_INT_SH(enable_ms_tree_icons); SAVE_INT(ms_confirm_removal); SAVE_INT(batch_mpeg_add_id3v1); SAVE_INT(batch_mpeg_add_id3v2); SAVE_INT(batch_mpeg_add_ape); SAVE_INT(metaedit_auto_clone); SAVE_INT(meta_use_basename_only); SAVE_INT(meta_rm_extension); SAVE_INT(meta_us_to_space); SAVE_INT(enable_tooltips); SAVE_INT(disable_buttons_relief); SAVE_INT_SH(combine_play_pause); SAVE_INT_SH(simple_view_in_fx); SAVE_INT(show_sn_title); SAVE_INT(united_minimization); SAVE_INT(magnify_smaller_images); SAVE_INT(cover_width); SAVE_INT(dont_show_cover); SAVE_INT(show_cover_for_ms_tracks_only); SAVE_INT(use_systray); SAVE_INT(systray_start_minimized); SAVE_INT_SH(hide_comment_pane); SAVE_INT_SH(enable_mstore_toolbar); SAVE_INT_SH(enable_mstore_statusbar); SAVE_INT(autoexpand_stores); SAVE_INT(show_hidden); SAVE_INT(main_window_always_on_top); SAVE_INT(tags_tab_first); SAVE_INT(disable_skin_support_settings); SAVE_INT(override_skin_settings); SAVE_INT(replaygain_tag_to_use); SAVE_FLOAT(vol); SAVE_FLOAT(bal); SAVE_INT(rva_is_enabled); SAVE_INT(rva_env); SAVE_FLOAT(rva_refvol); SAVE_FLOAT(rva_steepness); SAVE_INT(rva_use_averaging); SAVE_INT(rva_use_linear_thresh); SAVE_FLOAT(rva_avg_linear_thresh); SAVE_FLOAT(rva_avg_stddev_thresh); SAVE_FLOAT(rva_no_rva_voladj); SAVE_INT(main_pos_x); SAVE_INT(main_pos_y); SAVE_INT(main_size_x); if (options.playlist_is_embedded && !options.playlist_is_embedded_shadow && options.playlist_on) { snprintf(str, 31, "%d", options.main_size_y - playlist_window->allocation.height - 6); } else { snprintf(str, 31, "%d", options.main_size_y); } xmlNewTextChild(root, NULL, (const xmlChar *) "main_size_y", (xmlChar *) str); SAVE_INT(browser_pos_x); SAVE_INT(browser_pos_y); SAVE_INT(browser_size_x); SAVE_INT(browser_size_y); SAVE_INT(browser_on); SAVE_INT(browser_paned_pos); SAVE_INT(playlist_pos_x); SAVE_INT(playlist_pos_y); SAVE_INT(playlist_size_x); SAVE_INT(playlist_size_y); SAVE_INT(playlist_on); SAVE_INT_SH(playlist_is_embedded); SAVE_INT_SH(buttons_at_the_bottom); SAVE_INT(playlist_is_tree); SAVE_INT(playlist_always_show_tabs); SAVE_INT(playlist_show_close_button_in_tab); SAVE_INT(album_shuffle_mode); SAVE_INT_SH(enable_playlist_statusbar); SAVE_INT(ifpmanager_size_x); SAVE_INT(ifpmanager_size_y); SAVE_FONT(browser_font); SAVE_FONT(playlist_font); SAVE_FONT(bigtimer_font); SAVE_FONT(smalltimer_font); SAVE_FONT(songtitle_font); SAVE_FONT(songinfo_font); SAVE_FONT(statusbar_font); SAVE_COLOR(song_color); SAVE_COLOR(activesong_color); SAVE_INT(repeat_on); SAVE_INT(repeat_all_on); SAVE_INT(shuffle_on); SAVE_INT_ARRAY(time_idx, 0); SAVE_INT_ARRAY(time_idx, 1); SAVE_INT_ARRAY(time_idx, 2); SAVE_INT_ARRAY(plcol_idx, 0); SAVE_INT_ARRAY(plcol_idx, 1); SAVE_INT_ARRAY(plcol_idx, 2); SAVE_INT(search_pl_flags); SAVE_INT(search_ms_flags); SAVE_INT(cdda_drive_speed); SAVE_INT(cdda_paranoia_mode); SAVE_INT(cdda_paranoia_maxretries); SAVE_INT(cdda_force_drive_rescan); SAVE_INT(cdda_add_to_playlist); SAVE_INT(cdda_remove_from_playlist); SAVE_STR(cddb_server); SAVE_INT(cddb_timeout); SAVE_STR(cddb_email); SAVE_STR(cddb_local); SAVE_INT(cddb_cache_only); SAVE_INT(cddb_use_http); SAVE_INT(inet_use_proxy); SAVE_STR(inet_proxy); SAVE_INT(inet_proxy_port); SAVE_STR(inet_noproxy_domains); SAVE_INT(inet_timeout); SAVE_FLOAT(loop_range_start); SAVE_FLOAT(loop_range_end); SAVE_INT(wm_systray_warn); SAVE_INT(podcasts_autocheck); SAVE_INT(cdrip_deststore); SAVE_INT(cdrip_file_format); SAVE_INT(cdrip_bitrate); SAVE_INT(cdrip_vbr); SAVE_INT(cdrip_metadata); SAVE_STR(export_template); SAVE_INT(export_subdir_artist); SAVE_INT(export_subdir_album); SAVE_INT(export_subdir_limit); SAVE_INT(export_file_format); SAVE_INT(export_bitrate); SAVE_INT(export_vbr); SAVE_INT(export_metadata); SAVE_INT(export_filter_same); SAVE_INT(export_excl_enabled); SAVE_STR(export_excl_pattern); SAVE_INT(batch_tag_flags); SAVE_STR(ext_title_format_file); i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(ms_pathlist_store), &iter, NULL, i++)) { char * utf8; gtk_tree_model_get(GTK_TREE_MODEL(ms_pathlist_store), &iter, 0, &path, -1); utf8 = g_filename_to_utf8(path, -1, NULL, NULL, NULL); xmlNewTextChild(root, NULL, (const xmlChar *) "music_store", (xmlChar *) utf8); g_free(path); g_free(utf8); } save_systray_options(doc, root); sprintf(tmpname, "%s/config.xml.temp", options.confdir); xmlSaveFormatFile(tmpname, doc, 1); xmlFreeDoc(doc); if ((fin = fopen(config_file, "rt")) == NULL) { fprintf(stderr, "Error opening file: %s\n", config_file); return; } if ((fout = fopen(tmpname, "rt")) == NULL) { fprintf(stderr, "Error opening file: %s\n", tmpname); return; } c = 0; d = 0; while (((c = fgetc(fin)) != EOF) && ((d = fgetc(fout)) != EOF)) { if (c != d) { fclose(fin); fclose(fout); unlink(config_file); rename(tmpname, config_file); return; } } fclose(fin); fclose(fout); unlink(tmpname); } #define LOAD_STR(Var) \ if ((!xmlStrcmp(cur->name, (const xmlChar *) #Var))) { \ key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); \ if (key != NULL) \ strncpy(options.Var, (char *) key, MAXLEN-1); \ xmlFree(key); \ } #define LOAD_FONT(Font) \ if ((!xmlStrcmp(cur->name, (const xmlChar *)#Font))) { \ key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); \ if (key != NULL) \ strncpy(options.Font, (char *) key, MAX_FONTNAME_LEN-1); \ xmlFree(key); \ } #define LOAD_COLOR(Color) \ if ((!xmlStrcmp(cur->name, (const xmlChar *) #Color))) { \ key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); \ if (key != NULL) \ strncpy(options.Color, (char *) key, MAX_COLORNAME_LEN-1); \ xmlFree(key); \ } #define LOAD_INT(Var) \ if ((!xmlStrcmp(cur->name, (const xmlChar *) #Var))) { \ key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); \ if (key != NULL) \ sscanf((char *) key, "%d", &options.Var); \ xmlFree(key); \ } #define LOAD_INT_ARRAY(Var, Idx) \ if ((!xmlStrcmp(cur->name, (const xmlChar *) #Var "_" #Idx))) { \ key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); \ if (key != NULL) \ sscanf((char *) key, "%d", options.Var + Idx); \ xmlFree(key); \ } #define LOAD_INT_SH(Var) \ if ((!xmlStrcmp(cur->name, (const xmlChar *) #Var))) { \ key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); \ if (key != NULL) { \ sscanf((char *) key, "%d", &options.Var); \ options.Var##_shadow = options.Var; \ } \ xmlFree(key); \ } #define LOAD_FLOAT(Var) \ if ((!xmlStrcmp(cur->name, (const xmlChar *) #Var))) { \ key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); \ if (key != NULL) { \ options.Var = convf((char *) key); \ } \ xmlFree(key); \ } void load_config(void) { xmlDocPtr doc; xmlNodePtr cur; xmlNodePtr root; xmlChar * key; char config_file[MAXLEN]; FILE * f; sprintf(config_file, "%s/config.xml", options.confdir); if ((f = fopen(config_file, "rt")) == NULL) { /* no warning -- done that in core.c::load_default_cl() */ doc = xmlNewDoc((const xmlChar *) "1.0"); root = xmlNewNode(NULL, (const xmlChar *) "aqualung_config"); xmlDocSetRootElement(doc, root); xmlSaveFormatFile(config_file, doc, 1); xmlFreeDoc(doc); return; } fclose(f); doc = xmlParseFile(config_file); if (doc == NULL) { fprintf(stderr, "An XML error occured while parsing %s\n", config_file); return; } cur = xmlDocGetRootElement(doc); if (cur == NULL) { fprintf(stderr, "load_config: empty XML document\n"); xmlFreeDoc(doc); return; } if (xmlStrcmp(cur->name, (const xmlChar *)"aqualung_config")) { fprintf(stderr, "load_config: XML document of the wrong type, " "root node != aqualung_config\n"); xmlFreeDoc(doc); return; } if (!src_type_parsed) { options.src_type = 4; } options.vol = 0.0f; options.bal = 0.0f; options.repeat_on = 0; options.repeat_all_on = 0; options.shuffle_on = 0; options.loop_range_start = 0.0f; options.loop_range_end = 1.0f; options.wm_systray_warn = 1; options.podcasts_autocheck = 1; options.search_pl_flags = 0; options.search_ms_flags = SEARCH_F_AN | SEARCH_F_RT | SEARCH_F_TT | SEARCH_F_CO; options.browser_paned_pos = 400; options.skin[0] = '\0'; options.default_param[0] = '\0'; options.title_format[0] = '\0'; options.enable_tooltips = 1; options.show_sn_title = 1; options.united_minimization = 1; options.buttons_at_the_bottom = options.buttons_at_the_bottom_shadow = 0; options.combine_play_pause = options.combine_play_pause_shadow = 0; options.playlist_is_embedded = options.playlist_is_embedded_shadow = 1; options.playlist_is_tree = 1; options.playlist_show_close_button_in_tab = 1; options.enable_mstore_statusbar = options.enable_mstore_statusbar_shadow = 1; options.enable_mstore_toolbar = options.enable_mstore_toolbar_shadow = 1; options.enable_ms_tree_icons = options.enable_ms_tree_icons_shadow = 1; options.ms_statusbar_show_size = 1; options.ms_confirm_removal = 1; options.cover_width = 2; options.autoexpand_stores = 1; options.auto_save_playlist = 1; options.playlist_auto_save = 0; options.playlist_auto_save_int = 5; options.show_length_in_playlist = 1; options.enable_playlist_statusbar = options.enable_playlist_statusbar_shadow = 1; options.pl_statusbar_show_size = 1; options.rva_refvol = -12.0f; options.rva_steepness = 1.0f; options.rva_use_averaging = 1; options.rva_use_linear_thresh = 0; options.rva_avg_linear_thresh = 3.0f; options.rva_avg_stddev_thresh = 2.0f; options.batch_mpeg_add_id3v1 = 1; options.batch_mpeg_add_id3v2 = 1; options.batch_mpeg_add_ape = 0; options.metaedit_auto_clone = 0; options.cdda_drive_speed = 4; options.cdda_paranoia_mode = 0; /* no paranoia */ options.cdda_paranoia_maxretries = 20; options.cdda_force_drive_rescan = 0; options.cddb_server[0] = '\0'; options.cddb_email[0] = '\0'; options.cddb_local[0] = '\0'; options.cddb_timeout = 10; options.inet_use_proxy = 0; options.inet_proxy[0] = '\0'; options.inet_proxy_port = 8080; options.inet_noproxy_domains[0] = '\0'; options.inet_timeout = 5; options.time_idx[0] = 0; options.time_idx[1] = 1; options.time_idx[2] = 2; options.plcol_idx[0] = 0; options.plcol_idx[1] = 1; options.plcol_idx[2] = 2; options.cdrip_bitrate = 256; options.cdrip_vbr = 1; options.cdrip_metadata = 1; options.use_systray = 1; options.systray_start_minimized = 0; options.systray_mouse_wheel_horizontal = SYSTRAY_MW_CMD_DO_NOTHING; options.systray_mouse_wheel_vertical = SYSTRAY_MW_CMD_DO_NOTHING; options.systray_mouse_buttons_count = 0; options.systray_mouse_buttons = NULL; strcpy(options.export_template, "track%i.%x"); options.export_subdir_limit = 16; options.export_bitrate = 256; options.export_vbr = 1; options.export_metadata = 1; options.export_filter_same = 1; options.export_excl_pattern[0] = '\0'; options.ext_title_format_file[0] = '\0'; options.batch_tag_flags = BATCH_TAG_TITLE | BATCH_TAG_ARTIST | BATCH_TAG_ALBUM | BATCH_TAG_YEAR | BATCH_TAG_COMMENT | BATCH_TAG_TRACKNO; strncpy(options.song_color, "#888888", MAX_COLORNAME_LEN-1); ms_pathlist_store = gtk_list_store_new(3, G_TYPE_STRING, /* path */ G_TYPE_STRING, /* displayed name */ G_TYPE_STRING); /* state (rw, r, unreachable) */ cur = cur->xmlChildrenNode; while (cur != NULL) { LOAD_STR(audiodir); LOAD_STR(currdir); LOAD_STR(exportdir); LOAD_STR(plistdir); LOAD_STR(podcastdir); LOAD_STR(ripdir); LOAD_STR(storedir); LOAD_STR(default_param); LOAD_STR(title_format); LOAD_STR(skin); if (!src_type_parsed) { LOAD_INT(src_type); } LOAD_INT(ladspa_is_postfader); LOAD_INT(auto_save_playlist); LOAD_INT(playlist_auto_save); LOAD_INT(playlist_auto_save_int); LOAD_INT(batch_mpeg_add_id3v1); LOAD_INT(batch_mpeg_add_id3v2); LOAD_INT(batch_mpeg_add_ape); LOAD_INT(metaedit_auto_clone); LOAD_INT(meta_use_basename_only); LOAD_INT(meta_rm_extension); LOAD_INT(meta_us_to_space); LOAD_INT(show_rva_in_playlist); LOAD_INT(pl_statusbar_show_size); LOAD_INT(ms_statusbar_show_size); LOAD_INT(show_length_in_playlist); LOAD_INT(show_active_track_name_in_bold); LOAD_INT(auto_roll_to_active_track); LOAD_INT(enable_pl_rules_hint); LOAD_INT(enable_ms_rules_hint); LOAD_INT_SH(enable_ms_tree_icons); LOAD_INT(ms_confirm_removal); LOAD_INT(enable_tooltips); LOAD_INT(disable_buttons_relief); LOAD_INT_SH(combine_play_pause); LOAD_INT_SH(simple_view_in_fx); LOAD_INT(show_sn_title); LOAD_INT(united_minimization); LOAD_INT(magnify_smaller_images); LOAD_INT(cover_width); LOAD_INT(dont_show_cover); LOAD_INT(show_cover_for_ms_tracks_only); LOAD_INT(use_systray); LOAD_INT(systray_start_minimized); LOAD_INT_SH(hide_comment_pane); LOAD_INT_SH(enable_mstore_toolbar); LOAD_INT_SH(enable_mstore_statusbar); LOAD_INT(autoexpand_stores); LOAD_INT(show_hidden); LOAD_INT(main_window_always_on_top); LOAD_INT(tags_tab_first); LOAD_INT(disable_skin_support_settings); LOAD_INT(override_skin_settings); LOAD_INT(replaygain_tag_to_use); LOAD_FLOAT(vol); LOAD_FLOAT(bal); LOAD_INT(rva_is_enabled); LOAD_INT(rva_env); LOAD_FLOAT(rva_refvol); LOAD_FLOAT(rva_steepness); LOAD_INT(rva_use_averaging); LOAD_INT(rva_use_linear_thresh); LOAD_FLOAT(rva_avg_linear_thresh); LOAD_FLOAT(rva_avg_stddev_thresh); LOAD_FLOAT(rva_no_rva_voladj); LOAD_INT(main_pos_x); LOAD_INT(main_pos_y); LOAD_INT(main_size_x); LOAD_INT(main_size_y); LOAD_INT(browser_pos_x); LOAD_INT(browser_pos_y); LOAD_INT(browser_size_x); LOAD_INT(browser_size_y); LOAD_INT(browser_on); LOAD_INT(browser_paned_pos); LOAD_INT(playlist_pos_x); LOAD_INT(playlist_pos_y); LOAD_INT(playlist_size_x); LOAD_INT(playlist_size_y); LOAD_INT(playlist_on); LOAD_INT_SH(playlist_is_embedded); LOAD_INT_SH(buttons_at_the_bottom); LOAD_INT(playlist_is_tree); LOAD_INT(playlist_always_show_tabs); LOAD_INT(playlist_show_close_button_in_tab); LOAD_INT(album_shuffle_mode); LOAD_INT_SH(enable_playlist_statusbar); LOAD_INT(ifpmanager_size_x); LOAD_INT(ifpmanager_size_y); LOAD_FONT(browser_font); LOAD_FONT(playlist_font); LOAD_FONT(bigtimer_font); LOAD_FONT(smalltimer_font); LOAD_FONT(songtitle_font); LOAD_FONT(songinfo_font); LOAD_FONT(statusbar_font); LOAD_COLOR(song_color); LOAD_COLOR(activesong_color); LOAD_INT(repeat_on); LOAD_INT(repeat_all_on); LOAD_INT(shuffle_on); LOAD_INT_ARRAY(time_idx, 0); LOAD_INT_ARRAY(time_idx, 1); LOAD_INT_ARRAY(time_idx, 2); LOAD_INT_ARRAY(plcol_idx, 0); LOAD_INT_ARRAY(plcol_idx, 1); LOAD_INT_ARRAY(plcol_idx, 2); LOAD_INT(search_pl_flags); LOAD_INT(search_ms_flags); LOAD_INT(cdda_drive_speed); LOAD_INT(cdda_paranoia_mode); LOAD_INT(cdda_paranoia_maxretries); LOAD_INT(cdda_force_drive_rescan); LOAD_INT(cdda_add_to_playlist); LOAD_INT(cdda_remove_from_playlist); LOAD_STR(cddb_server); LOAD_INT(cddb_timeout); LOAD_STR(cddb_email); LOAD_STR(cddb_local); LOAD_INT(cddb_cache_only); LOAD_INT(cddb_use_http); LOAD_INT(inet_use_proxy); LOAD_STR(inet_proxy); LOAD_INT(inet_proxy_port); LOAD_STR(inet_noproxy_domains); LOAD_INT(inet_timeout); LOAD_FLOAT(loop_range_start); LOAD_FLOAT(loop_range_end); LOAD_INT(wm_systray_warn); LOAD_INT(podcasts_autocheck); LOAD_INT(cdrip_deststore); LOAD_INT(cdrip_file_format); LOAD_INT(cdrip_bitrate); LOAD_INT(cdrip_vbr); LOAD_INT(cdrip_metadata); LOAD_STR(export_template); LOAD_INT(export_subdir_artist); LOAD_INT(export_subdir_album); LOAD_INT(export_subdir_limit); LOAD_INT(export_file_format); LOAD_INT(export_bitrate); LOAD_INT(export_vbr); LOAD_INT(export_metadata); LOAD_INT(export_filter_same); LOAD_INT(export_excl_enabled); LOAD_STR(export_excl_pattern); LOAD_INT(batch_tag_flags); LOAD_STR(ext_title_format_file); if ((!xmlStrcmp(cur->name, (const xmlChar *)"music_store"))) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); if (key != NULL) { char path[MAXLEN]; char * ppath; snprintf(path, MAXLEN - 1, "%s", (char *)key); ppath = g_filename_from_utf8(path, -1, NULL, NULL, NULL); append_ms_pathlist(ppath, path); g_free(ppath); } xmlFree(key); } else if ((!xmlStrcmp(cur->name, (const xmlChar *) "systray"))) { load_systray_options(doc, cur); } cur = cur->next; } { char buf[MAXLEN]; if (!options.title_format[0] || make_string_va(buf, options.title_format, 'a', "a", 'r', "r", 't', "t", 0) != 0) { strcpy(options.title_format, "%a?ar|at{ :: }%r?rt{ :: }%t"); } } #ifdef HAVE_LUA setup_extended_title_formatting(); #endif /* HAVE_LUA */ xmlFreeDoc(doc); return; } void save_systray_options(xmlDocPtr doc, xmlNodePtr root) { xmlNodePtr cur; char str[MAXLEN]; int i; if (root == NULL) return; cur = xmlNewNode(NULL, (const xmlChar *) "systray"); xmlAddChild(root, cur); root = cur; SAVE_INT(systray_mouse_wheel_horizontal); SAVE_INT(systray_mouse_wheel_vertical); for (i = 0; i < options.systray_mouse_buttons_count; i++) { cur = xmlNewNode(NULL, (const xmlChar *) "mouse_button"); xmlAddChild(root, cur); snprintf(str, sizeof(str), "%d", options.systray_mouse_buttons[i].button_nr); xmlSetProp(cur, (const xmlChar *) "number", (const xmlChar *) str); snprintf(str, sizeof(str), "%d", options.systray_mouse_buttons[i].command); xmlSetProp(cur, (const xmlChar *) "command", (const xmlChar *) str); } } void load_systray_options(xmlDocPtr doc, xmlNodePtr cur) { xmlChar * key; int button_nr, command; if (cur == NULL) return; cur = cur->xmlChildrenNode; while (cur != NULL) { LOAD_INT(systray_mouse_wheel_horizontal); LOAD_INT(systray_mouse_wheel_vertical); if ((!xmlStrcmp(cur->name, (const xmlChar *) "mouse_button"))) { key = xmlGetProp(cur, (const xmlChar *) "number"); if (key != NULL) { sscanf((char *) key, "%d", &button_nr); xmlFree(key); key = xmlGetProp(cur, (const xmlChar *) "command"); if (key != NULL) { sscanf((char *) key, "%d", &command); xmlFree(key); // Disallow Left and Right mouse button (reserved). if (button_nr != 1 && button_nr != 3 && command >= 0 && command < SYSTRAY_MB_CMD_LAST) { ++options.systray_mouse_buttons_count; options.systray_mouse_buttons = realloc(options.systray_mouse_buttons, options.systray_mouse_buttons_count * sizeof(mouse_button_command_t)); options.systray_mouse_buttons[options.systray_mouse_buttons_count-1].button_nr = button_nr; options.systray_mouse_buttons[options.systray_mouse_buttons_count-1].command = command; } } } } cur = cur->next; } } void finalize_options(void) { options.systray_mouse_buttons_count = 0; free(options.systray_mouse_buttons); options.systray_mouse_buttons = NULL; } // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/playlist.h0000644000175000001440000001277111315737506013733 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: playlist.h 1086 2009-12-27 15:25:09Z peterszilagyi $ */ #ifndef _PLAYLIST_H #define _PLAYLIST_H #include #include "common.h" #ifdef _WIN32 #include #else #include #endif /* _WIN32 */ enum { PLAYLIST_LOAD, PLAYLIST_LOAD_TAB, PLAYLIST_ENQUEUE }; typedef struct { AQUALUNG_THREAD_DECLARE(thread_id) AQUALUNG_MUTEX_DECLARE(thread_mutex) AQUALUNG_MUTEX_DECLARE(wait_mutex) AQUALUNG_COND_DECLARE(thread_wait) volatile int thread_stop; int progbar_semaphore; int ms_semaphore; int index; char name[MAXLEN]; int name_set; int playing; int closed; GtkTreeStore * store; GtkTreeSelection * select; GtkWidget * view; GtkWidget * scroll; GtkWidget * label; GtkWidget * tab_close_button; GtkWidget * tab_menu; GtkWidget * tab__close_undo; GtkTreeViewColumn * track_column; GtkTreeViewColumn * rva_column; GtkTreeViewColumn * length_column; GtkWidget * progbar; GtkWidget * progbar_container; GtkWidget * progbar_stop_button; GtkWidget * widget; } playlist_t; typedef struct { playlist_t * pl; volatile int data_written; int threshold; GSList * list; GList * pldata_list; void * xml_doc; void * xml_node; int * xml_ref; char * filename; int clear; int start_playback; } playlist_transfer_t; playlist_t * playlist_tab_new(char * name); playlist_t * playlist_tab_new_if_nonempty(char * name); playlist_t * playlist_get_current(void); void playlist_set_current(playlist_t * pl); playlist_t * playlist_get_playing(void); GtkTreePath * playlist_get_playing_path(playlist_t * pl); void playlist_reorder_columns_all(int * order); void playlist_show_hide_close_buttons(gboolean state); void create_playlist(void); void show_playlist(void); void hide_playlist(void); void playlist_set_playing(playlist_t * pl, int playing); void playlist_stats_set_busy(void); void playlist_progress_bar_show(playlist_t * pl); void playlist_progress_bar_hide_all(void); void show_hide_close_buttons(gboolean state); void playlist_ensure_tab_exists(void); void playlist_load(GSList * list, int mode, char * tab_name, int start_playback); void playlist_save(playlist_t * pl, char * filename); void playlist_save_m3u(playlist_t * pl, char * filename); void playlist_save_all(char * filename); void playlist_auto_save_reset(void); void playlist_set_color(void); void playlist_reset_display_names(void); void playlist_disable_bold_font(void); void playlist_set_font(int cond); void playlist_content_changed(playlist_t * pl); void playlist_selection_changed(playlist_t * pl); void playlist_drag_end(GtkWidget * widget, GdkDragContext * drag_context, gpointer data); void playlist_menu_set_popup_sensitivity(playlist_t * pl); gint playlist_window_key_pressed(GtkWidget * widget, GdkEventKey * kevent); void playlist_foreach_selected(playlist_t * pl, int (* foreach)(playlist_t *, GtkTreeIter *, void *), void * data); void recalc_album_node(playlist_t * pl, GtkTreeIter * iter); void mark_track(playlist_t * pl, GtkTreeIter * piter); void unmark_track(playlist_t * pl, GtkTreeIter * piter); void show_active_position_in_playlist(playlist_t * pl); #ifdef HAVE_CDDA void playlist_add_cdda(GtkTreeIter * iter_drive, unsigned long hash); void playlist_remove_cdda(char * device_path); #endif /* HAVE_CDDA */ enum { PL_FLAG_ACTIVE = (1 << 0), PL_FLAG_COVER = (1 << 1), PL_FLAG_ALBUM_NODE = (1 << 2), PL_FLAG_ALBUM_CHILD = (1 << 3) }; typedef struct { char * artist; char * album; char * title; /* NULL for album nodes */ char * file; /* NULL for album nodes */ char * display; /* Already formatted title ready for display */ float voladj; /* volume adjustment [dB] */ float duration; /* length in seconds */ unsigned size; /* file size in bytes */ unsigned short ntracks; /* number of children nodes (for album nodes only) */ unsigned short actrack; /* active children node (for album nodes only) */ int flags; } playlist_data_t; playlist_data_t * playlist_data_new(void); void playlist_data_get_display_name(char * list_str, playlist_data_t * pldata); #define PL_IS_SET_FLAG(plist, flag) (plist->flags & flag) #define PL_SET_FLAG(plist, flag) (plist->flags |= flag) #define PL_UNSET_FLAG(plist, flag) (plist->flags &= ~flag) #define IS_PL_ACTIVE(plist) PL_IS_SET_FLAG(plist, PL_FLAG_ACTIVE) #define IS_PL_COVER(plist) PL_IS_SET_FLAG(plist, PL_FLAG_COVER) #define IS_PL_ALBUM_NODE(plist) PL_IS_SET_FLAG(plist, PL_FLAG_ALBUM_NODE) #define IS_PL_ALBUM_CHILD(plist) PL_IS_SET_FLAG(plist, PL_FLAG_ALBUM_CHILD) #define IS_PL_TOPLEVEL(plist) (IS_PL_ALBUM_NODE(plist) || !IS_PL_ALBUM_CHILD(plist)) enum { PL_COL_NAME = 0, PL_COL_VADJ, PL_COL_DURA, PL_COL_COLO, PL_COL_FONT, PL_COL_DATA, PL_COL_COUNT }; #endif /* _PLAYLIST_H */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/playlist.c0000644000175000001440000045731311324131225013715 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: playlist.c 1093 2010-01-05 14:12:15Z peterszilagyi $ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "common.h" #include "utils.h" #include "utils_gui.h" #include "core.h" #include "httpc.h" #include "rb.h" #include "cdda.h" #include "gui_main.h" #include "music_browser.h" #include "file_info.h" #include "decoder/dec_mod.h" #include "decoder/file_decoder.h" #include "metadata_api.h" #include "volume.h" #include "options.h" #include "i18n.h" #include "search_playlist.h" #include "playlist.h" #include "ifp_device.h" #include "export.h" #ifdef HAVE_LUA #include "ext_title_format.h" #endif /* HAVE_LUA */ extern options_t options; extern char pl_color_active[14]; extern char pl_color_inactive[14]; extern GtkTooltips * aqualung_tooltips; extern PangoFontDescription *fd_playlist; extern PangoFontDescription *fd_statusbar; extern GtkWidget * main_window; extern GtkWidget * info_window; extern GtkTreeSelection * music_select; extern gulong play_id; extern gulong pause_id; extern GtkWidget * play_button; extern GtkWidget * pause_button; extern int is_file_loaded; extern int is_paused; extern int allow_seeks; extern char current_file[MAXLEN]; extern rb_t * rb_gui2disk; extern GtkWidget * playlist_toggle; GtkWidget * playlist_window; GtkWidget * playlist_color_indicator; gint playlist_scroll_up_tag = -1; gint playlist_scroll_dn_tag = -1; GtkWidget * statusbar_total; GtkWidget * statusbar_selected; GtkWidget * statusbar_total_label; GtkWidget * statusbar_selected_label; /* popup menus */ GtkWidget * add_menu; GtkWidget * add__files; GtkWidget * add__dir; GtkWidget * add__url; GtkWidget * sel_menu; GtkWidget * sel__none; GtkWidget * sel__all; GtkWidget * sel__inv; GtkWidget * rem_menu; GtkWidget * cut__sel; GtkWidget * rem__all; GtkWidget * rem__dead; GtkWidget * rem__sel; GtkWidget * plist_menu; GtkWidget * plist__tab_new; GtkWidget * plist__save; GtkWidget * plist__save_all; GtkWidget * plist__load; GtkWidget * plist__enqueue; GtkWidget * plist__load_tab; GtkWidget * plist__rva; GtkWidget * plist__rva_menu; GtkWidget * plist__rva_separate; GtkWidget * plist__rva_average; GtkWidget * plist__reread_file_meta; GtkWidget * plist__fileinfo; GtkWidget * plist__search; GtkWidget * plist__roll; #ifdef HAVE_IFP GtkWidget * plist__send_songs_to_iriver; #endif /* HAVE_IFP */ #ifdef HAVE_EXPORT GtkWidget * plist__export; #endif /* HAVE_EXPORT */ gchar command[RB_CONTROL_SIZE]; gchar fileinfo_name[MAXLEN]; gchar fileinfo_file[MAXLEN]; int fileinfo_cover; int playlist_dirty; int playlist_auto_save_tag = -1; typedef struct { GtkTreeStore * store; int has_album_node; } clipboard_t; clipboard_t * clipboard; enum { PLAYLIST_INVALID, PLAYLIST_XML_SINGLE, PLAYLIST_XML_MULTI, PLAYLIST_M3U, PLAYLIST_PLS }; void create_playlist_gui(playlist_t * pl); void playlist_notebook_prev_page(void); void playlist_notebook_next_page(void); void playlist_tab_close(GtkButton * button, gpointer data); void playlist_tab_close_undo(void); void playlist_progress_bar_hide(playlist_t * pl); playlist_transfer_t * playlist_transfer_get(int mode, char * tab_name, int start_playback); playlist_data_t * playlist_filemeta_get(char * filename); void playlist_unlink_files(playlist_t * pl); void set_cursor_in_playlist(playlist_t * pl, GtkTreeIter *iter, gboolean scroll); void select_active_position_in_playlist(playlist_t * pl); void playlist_selection_changed(playlist_t * pl); void playlist_selection_changed_cb(GtkTreeSelection * select, gpointer data); void sel__all_cb(gpointer data); void sel__none_cb(gpointer data); void rem__all_cb(gpointer data); void rem__sel_cb(gpointer data); void cut__sel_cb(gpointer data); void plist__search_cb(gpointer data); void plist__roll_cb(gpointer data); void rem_all(playlist_t * pl); void add_files(GtkWidget * widget, gpointer data); void tab__rename_cb(gpointer data); void add_directory(GtkWidget * widget, gpointer data); void init_plist_menu(GtkWidget *append_menu); void show_active_position_in_playlist(playlist_t * pl); void show_active_position_in_playlist_toggle(playlist_t * pl); void expand_collapse_album_node(playlist_t * pl); void playlist_save(playlist_t * pl, char * filename); int playlist_get_type(char * filename); void playlist_load_xml_multi(char * filename, int start_playback); void playlist_load_xml_single(char * filename, playlist_transfer_t * pt); void * playlist_load_m3u_thread(void * arg); void * playlist_load_pls_thread(void * arg); void roll_to_active_track(playlist_t * pl, GtkTreeIter *piter); GtkWidget * playlist_notebook; GList * playlists; GList * playlists_closed; playlist_data_t * playlist_data_new() { playlist_data_t * data; if ((data = (playlist_data_t *)calloc(1, sizeof(playlist_data_t))) == NULL) { fprintf(stderr, "playlist_data_new(): calloc error\n"); return NULL; } data->voladj = 0.0f; data->duration = 0.0f; data->size = 0; data->flags = 0; data->artist = NULL; data->album = NULL; data->title = NULL; data->display = NULL; data->file = NULL; return data; } void playlist_data_copy_noalloc(playlist_data_t * dest, playlist_data_t * src) { if (src->artist) { free_strdup(&dest->artist, src->artist); } if (src->album) { free_strdup(&dest->album, src->album); } if (src->title) { free_strdup(&dest->title, src->title); } if (src->display) { free_strdup(&dest->display, src->display); } if (src->file) { free_strdup(&dest->file, src->file); } dest->voladj = src->voladj; dest->duration = src->duration; dest->size = src->size; dest->ntracks = src->ntracks; dest->actrack = src->actrack; dest->flags = src->flags; } playlist_data_t * playlist_data_copy(playlist_data_t * src) { playlist_data_t * dest; if ((dest = playlist_data_new()) == NULL) { return NULL; } playlist_data_copy_noalloc(dest, src); return dest; } void playlist_data_free(playlist_data_t * data) { if (data->artist) { free(data->artist); data->artist = NULL; } if (data->album) { free(data->album); data->album = NULL; } if (data->title) { free(data->title); data->title = NULL; } if (data->display) { free(data->display); data->display = NULL; } if (data->file) { free(data->file); data->file = NULL; } free(data); } gboolean playlist_remove_track(GtkTreeStore * store, GtkTreeIter * iter) { playlist_data_t * data; gtk_tree_model_get(GTK_TREE_MODEL(store), iter, PL_COL_DATA, &data, -1); playlist_data_free(data); return gtk_tree_store_remove(store, iter); } void playlist_clear(GtkTreeStore * store) { GtkTreeIter iter; GtkTreeIter iter_child; playlist_data_t * data; int i, j; i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(store), &iter, NULL, i++)) { gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, PL_COL_DATA, &data, -1); playlist_data_free(data); j = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(store), &iter_child, &iter, j++)) { gtk_tree_model_get(GTK_TREE_MODEL(store), &iter_child, PL_COL_DATA, &data, -1); playlist_data_free(data); } } gtk_tree_store_clear(store); } GtkTreeStore * playlist_store_new() { return gtk_tree_store_new(PL_COL_COUNT, G_TYPE_STRING, /* title string */ G_TYPE_STRING, /* volume adj. displayed */ G_TYPE_STRING, /* duration displayed */ G_TYPE_STRING, /* color */ G_TYPE_INT, /* font weight */ G_TYPE_POINTER); /* pointer to struct playlist_data_t */ } playlist_t * playlist_new(char * name) { playlist_t * pl = NULL; if ((pl = (playlist_t *)calloc(1, sizeof(playlist_t))) == NULL) { fprintf(stderr, "playlist_new(): calloc error\n"); return NULL; } playlists = g_list_append(playlists, pl); AQUALUNG_COND_INIT(pl->thread_wait); #ifdef _WIN32 pl->thread_mutex = g_mutex_new(); pl->wait_mutex = g_mutex_new(); pl->thread_wait = g_cond_new(); #endif if (name != NULL) { strncpy(pl->name, name, MAXLEN-1); pl->name_set = 1; } else { strncpy(pl->name, _("(Untitled)"), MAXLEN-1); } pl->index = -1; pl->store = playlist_store_new(); return pl; } void playlist_free(playlist_t * pl) { playlists = g_list_remove(playlists, pl); #ifdef _WIN32 g_mutex_free(pl->thread_mutex); g_mutex_free(pl->wait_mutex); g_cond_free(pl->thread_wait); #endif free(pl); } gint playlist_compare_widget(gconstpointer list, gconstpointer widget) { return ((playlist_t *)list)->widget != widget; } gint playlist_compare_playing(gconstpointer list, gconstpointer dummy) { return ((playlist_t *)list)->playing == 0; } gint playlist_compare_name(gconstpointer list, gconstpointer name) { return strcmp(((playlist_t *)list)->name, (char *)name); } gint playlist_compare_index(gconstpointer p1, gconstpointer p2) { int i1 = ((playlist_t *)p1)->index; int i2 = ((playlist_t *)p2)->index; if (i1 == -1) { i1 = 1000; } if (i2 == -1) { i2 = 1000; } if (i1 < i2) { return -1; } else if (i1 > i2) { return 1; } return 0; } playlist_t * playlist_find(gconstpointer data, GCompareFunc func) { GList * find = g_list_find_custom(playlists, data, func); if (find != NULL) { return (playlist_t *)(find->data); } return NULL; } playlist_t * playlist_get_current() { int idx = gtk_notebook_get_current_page(GTK_NOTEBOOK(playlist_notebook)); GtkWidget * widget = gtk_notebook_get_nth_page(GTK_NOTEBOOK(playlist_notebook), idx); return playlist_find(widget, playlist_compare_widget); } playlist_t * playlist_get_playing() { return playlist_find(NULL/*dummy*/, playlist_compare_playing); } playlist_t * playlist_get_by_page_num(int num) { GtkWidget * widget = gtk_notebook_get_nth_page(GTK_NOTEBOOK(playlist_notebook), num); playlist_t * pl = playlist_find(widget, playlist_compare_widget); if (pl == NULL) { fprintf(stderr, "WARNING: playlist_get_by_page_num() == NULL\n"); } return pl; } playlist_t * playlist_get_by_name(char * name) { return playlist_find(name, playlist_compare_name); } void playlist_set_current(playlist_t * pl) { int n = gtk_notebook_get_n_pages(GTK_NOTEBOOK(playlist_notebook)); int i; for (i = 0; i < n; i++) { if (pl->widget == gtk_notebook_get_nth_page(GTK_NOTEBOOK(playlist_notebook), i)) { gtk_notebook_set_current_page(GTK_NOTEBOOK(playlist_notebook), i); return; } } } int playlist_is_empty(playlist_t * pl) { GtkTreeIter dummy; if (!pl->name_set && gtk_tree_model_get_iter_first(GTK_TREE_MODEL(pl->store), &dummy) == FALSE) { return 1; } return 0; } void playlist_set_active(GtkTreeStore * store, GtkTreeIter * piter) { playlist_data_t * data; gtk_tree_model_get(GTK_TREE_MODEL(store), piter, PL_COL_DATA, &data, -1); PL_SET_FLAG(data, PL_FLAG_ACTIVE); gtk_tree_store_set(store, piter, PL_COL_COLO, pl_color_active, -1); if (options.show_active_track_name_in_bold) { gtk_tree_store_set(store, piter, PL_COL_FONT, PANGO_WEIGHT_BOLD, -1); } } void playlist_set_inactive(GtkTreeStore * store, GtkTreeIter * piter) { playlist_data_t * data; gtk_tree_model_get(GTK_TREE_MODEL(store), piter, PL_COL_DATA, &data, -1); PL_UNSET_FLAG(data, PL_FLAG_ACTIVE); gtk_tree_store_set(store, piter, PL_COL_COLO, pl_color_inactive, PL_COL_FONT, PANGO_WEIGHT_NORMAL, -1); } void playlist_node_copy(GtkTreeStore * sstore, GtkTreeIter * siter, GtkTreeStore * tstore, GtkTreeIter * titer, GtkTreeIter * iter, int mode) { gchar * name; gchar * vadj; gchar * dura; playlist_data_t * sdata; playlist_data_t * tdata; gtk_tree_model_get(GTK_TREE_MODEL(sstore), siter, PL_COL_NAME, &name, PL_COL_VADJ, &vadj, PL_COL_DURA, &dura, PL_COL_DATA, &sdata, -1); if ((tdata = playlist_data_copy(sdata)) == NULL) { return; } if (mode == 0) { gtk_tree_store_insert_after(tstore, iter, NULL, titer); } else if (mode == 1) { gtk_tree_store_insert_before(tstore, iter, NULL, titer); } else { gtk_tree_store_append(tstore, iter, titer); } if (tdata->file) { GtkTreeIter parent; int name_set = 0; if (gtk_tree_model_iter_parent(GTK_TREE_MODEL(tstore), &parent, iter)) { playlist_data_t * pdata; gtk_tree_model_get(GTK_TREE_MODEL(tstore), &parent, PL_COL_DATA, &pdata, -1); if (pdata->artist && tdata->artist && pdata->album && tdata->album && tdata->title && !strcmp(pdata->artist, tdata->artist) && !strcmp(pdata->album, tdata->album)) { gtk_tree_store_set(tstore, iter, PL_COL_NAME, tdata->title, -1); name_set = 1; } } if (!name_set) { char list_str[MAXLEN]; playlist_data_get_display_name(list_str, tdata); gtk_tree_store_set(tstore, iter, PL_COL_NAME, list_str, -1); } } else { gtk_tree_store_set(tstore, iter, PL_COL_NAME, name, -1); } gtk_tree_store_set(tstore, iter, PL_COL_VADJ, vadj, PL_COL_DURA, dura, PL_COL_COLO, IS_PL_ACTIVE(tdata) ? pl_color_active : pl_color_inactive, PL_COL_FONT, (IS_PL_ACTIVE(tdata) && options.show_active_track_name_in_bold) ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL, PL_COL_DATA, tdata, -1); if (sstore != tstore && IS_PL_ACTIVE(sdata)) { playlist_set_inactive(tstore, iter); if (IS_PL_ALBUM_NODE(tdata)) { char name[MAXLEN]; snprintf(name, MAXLEN-1, "%s: %s", tdata->artist, tdata->album); gtk_tree_store_set(tstore, iter, PL_COL_NAME, name, -1); } } g_free(name); g_free(vadj); g_free(dura); } void playlist_node_deep_copy(GtkTreeStore * sstore, GtkTreeIter * siter, GtkTreeStore * tstore, GtkTreeIter * titer, int mode) { GtkTreeIter iter; GtkTreeIter dummy; GtkTreeIter child_siter; int i; playlist_node_copy(sstore, siter, tstore, titer, &iter, mode); i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(sstore), &child_siter, siter, i++)) { playlist_node_copy(sstore, &child_siter, tstore, &iter, &dummy, 2/*append*/); } } int all_tracks_selected(playlist_t * pl, GtkTreeIter * piter) { gint j = 0; GtkTreeIter iter_child; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(pl->store), &iter_child, piter, j++)) { if (!gtk_tree_selection_iter_is_selected(pl->select, &iter_child)) { return 0; } } return 1; } void playlist_copy(playlist_t * pl) { GtkTreeIter iter; gint i = 0; if (clipboard == NULL) { if ((clipboard = (clipboard_t *)calloc(1, sizeof(clipboard_t))) == NULL) { fprintf(stderr, "playlist_copy(): calloc error\n"); return; } clipboard->store = playlist_store_new(); } else { playlist_clear(clipboard->store); } clipboard->has_album_node = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(pl->store), &iter, NULL, i++)) { if (gtk_tree_selection_iter_is_selected(pl->select, &iter)) { playlist_node_deep_copy(pl->store, &iter, clipboard->store, NULL, 2); clipboard->has_album_node = 1; continue; } if (gtk_tree_model_iter_n_children(GTK_TREE_MODEL(pl->store), &iter) == 0) { continue; } if (all_tracks_selected(pl, &iter)) { playlist_node_deep_copy(pl->store, &iter, clipboard->store, NULL, 2); clipboard->has_album_node = 1; } else { int j = 0; GtkTreeIter iter_child; GtkTreeIter dummy; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(pl->store), &iter_child, &iter, j++)) { if (gtk_tree_selection_iter_is_selected(pl->select, &iter_child)) { playlist_node_copy(pl->store, &iter_child, clipboard->store, NULL, &dummy, 2); } } } } } void playlist_cut(playlist_t * pl) { playlist_copy(pl); rem__sel_cb(pl); } void playlist_paste(playlist_t * pl, int before) { gint i = 0; GtkTreeIter iter; GtkTreeIter titer; GtkTreePath * path; if (clipboard == NULL) { return; } gtk_tree_view_get_cursor(GTK_TREE_VIEW(pl->view), &path, NULL); if (path != NULL) { if (clipboard->has_album_node && gtk_tree_path_get_depth(path) > 1) { gtk_tree_path_free(path); return; } gtk_tree_model_get_iter(GTK_TREE_MODEL(pl->store), &titer, path); } while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(clipboard->store), &iter, NULL, i++)) { if (path == NULL) { playlist_node_deep_copy(clipboard->store, &iter, pl->store, NULL, 2); } else { if (before) { playlist_node_deep_copy(clipboard->store, &iter, pl->store, &titer, 1); } else { playlist_node_deep_copy(clipboard->store, &iter, pl->store, &titer, 0); gtk_tree_model_iter_next(GTK_TREE_MODEL(pl->store), &titer); } } } if (path != NULL) { gtk_tree_path_free(path); } playlist_content_changed(pl); } playlist_transfer_t * playlist_transfer_new(playlist_t * pl) { playlist_transfer_t * pt = NULL; if ((pt = (playlist_transfer_t *)calloc(1, sizeof(playlist_transfer_t))) == NULL) { fprintf(stderr, "playlist_transfer_new(): calloc error\n"); return NULL; } if (pl == NULL) { if ((pt->pl = playlist_get_current()) == NULL) { free(pt); return NULL; } } else { pt->pl = pl; } pt->threshold = 1; return pt; } void playlist_transfer_free(playlist_transfer_t * pt) { if (pt->xml_ref != NULL) { *(pt->xml_ref) -= 1; if (*(pt->xml_ref) == 0) { xmlFreeDoc((xmlDocPtr)pt->xml_doc); free(pt->xml_ref); } } else if (pt->xml_doc != NULL) { xmlFreeDoc((xmlDocPtr)pt->xml_doc); } if (pt->filename) { free(pt->filename); } free(pt); } void playlist_reset_display_names(void) { GList * node = NULL; playlist_data_t * data = NULL; char list_str[MAXLEN]; for (node = playlists; node; node = node->next) { playlist_t * pl = (playlist_t *)node->data; GtkTreeIter iter; int i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(pl->store), &iter, NULL, i++)) { if (!gtk_tree_model_iter_has_child(GTK_TREE_MODEL(pl->store), &iter)) { gtk_tree_model_get(GTK_TREE_MODEL(pl->store), &iter, PL_COL_DATA, &data, -1); if (!httpc_is_url(data->file)) { playlist_data_get_display_name(list_str, data); gtk_tree_store_set(pl->store, &iter, PL_COL_NAME, list_str, -1); } } } } } void playlist_disable_bold_font_foreach(gpointer data, gpointer user_data) { GtkTreeIter iter; gint i = 0; GtkTreeStore * store = ((playlist_t *)data)->store; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(store), &iter, NULL, i++)) { gint j = 0; GtkTreeIter iter_child; gtk_tree_store_set(store, &iter, PL_COL_FONT, PANGO_WEIGHT_NORMAL, -1); while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(store), &iter_child, &iter, j++)) { gtk_tree_store_set(store, &iter_child, PL_COL_FONT, PANGO_WEIGHT_NORMAL, -1); } } } void playlist_disable_bold_font(void) { g_list_foreach(playlists, playlist_disable_bold_font_foreach, NULL); } void playlist_set_font_foreach(gpointer data, gpointer user_data) { gtk_widget_modify_font(((playlist_t *)data)->view, fd_playlist); } void playlist_set_font(int cond) { if (cond) { gtk_widget_modify_font(statusbar_selected, fd_statusbar); gtk_widget_modify_font(statusbar_selected_label, fd_statusbar); gtk_widget_modify_font(statusbar_total, fd_statusbar); gtk_widget_modify_font(statusbar_total_label, fd_statusbar); g_list_foreach(playlists, playlist_set_font_foreach, NULL); } } void playlist_set_markup(playlist_t * pl) { if (pl->playing) { gchar * str = g_markup_printf_escaped("%s", pl->name); gtk_label_set_markup(GTK_LABEL(pl->label), str); g_free(str); gtk_widget_modify_fg(pl->label, GTK_STATE_NORMAL, &playlist_color_indicator->style->fg[GTK_STATE_ACTIVE]); gtk_widget_modify_fg(pl->label, GTK_STATE_ACTIVE, &playlist_color_indicator->style->fg[GTK_STATE_ACTIVE]); } else { gtk_label_set_text(GTK_LABEL(pl->label), pl->name); gtk_widget_modify_fg(pl->label, GTK_STATE_NORMAL, &playlist_color_indicator->style->fg[GTK_STATE_NORMAL]); gtk_widget_modify_fg(pl->label, GTK_STATE_ACTIVE, &playlist_color_indicator->style->fg[GTK_STATE_NORMAL]); } } void playlist_set_playing(playlist_t * pl, int playing) { pl->playing = playing; playlist_set_markup(pl); } void adjust_playlist_item_color(GtkTreeStore * store, GtkTreeIter * iter, char * active, char * inactive) { playlist_data_t * data; gtk_tree_model_get(GTK_TREE_MODEL(store), iter, PL_COL_DATA, &data, -1); if (IS_PL_ACTIVE(data)) { gtk_tree_store_set(store, iter, PL_COL_COLO, active, -1); if (options.show_active_track_name_in_bold) { gtk_tree_store_set(store, iter, PL_COL_FONT, PANGO_WEIGHT_BOLD, -1); } } else { gtk_tree_store_set(store, iter, PL_COL_COLO, inactive, PL_COL_FONT, PANGO_WEIGHT_NORMAL, -1); } } void adjust_playlist_color(playlist_t * pl, char * active, char * inactive) { int i = 0; GtkTreeIter iter; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(pl->store), &iter, NULL, i++)) { int j = 0; GtkTreeIter iter_child; adjust_playlist_item_color(pl->store, &iter, active, inactive); while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(pl->store), &iter_child, &iter, j++)) { adjust_playlist_item_color(pl->store, &iter_child, active, inactive); } } } void playlist_set_color(void) { GList * node = NULL; char active[14]; char inactive[14]; GdkColor color; int rs = 0, gs = 0, bs = 0; int ri = 0, gi = 0, bi = 0; if (options.override_skin_settings && (gdk_color_parse(options.activesong_color, &color) == TRUE)) { rs = color.red; gs = color.green; bs = color.blue; if (rs == 0 && gs == 0 && bs == 0) { rs = 1; } } else { rs = playlist_color_indicator->style->fg[SELECTED].red; gs = playlist_color_indicator->style->fg[SELECTED].green; bs = playlist_color_indicator->style->fg[SELECTED].blue; } if (options.override_skin_settings && (gdk_color_parse(options.song_color, &color) == TRUE)) { ri = color.red; gi = color.green; bi = color.blue; } else { ri = playlist_color_indicator->style->fg[INSENSITIVE].red; gi = playlist_color_indicator->style->fg[INSENSITIVE].green; bi = playlist_color_indicator->style->fg[INSENSITIVE].blue; } sprintf(active, "#%04X%04X%04X", rs, gs, bs); sprintf(inactive, "#%04X%04X%04X", ri, gi, bi); for (node = playlists; node; node = node->next) { playlist_t * pl = (playlist_t *)node->data; adjust_playlist_color(pl, active, inactive); playlist_set_playing(pl, pl->playing); } for (node = playlists_closed; node; node = node->next) { playlist_t * pl = (playlist_t *)node->data; adjust_playlist_color(pl, active, inactive); } strcpy(pl_color_active, active); strcpy(pl_color_inactive, inactive); } void playlist_foreach_selected(playlist_t * pl, int (* foreach)(playlist_t *, GtkTreeIter *, void *), void * data) { GtkTreeIter iter_top; GtkTreeIter iter; gint i; gint j; i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(pl->store), &iter_top, NULL, i++)) { gboolean topsel = gtk_tree_selection_iter_is_selected(pl->select, &iter_top); if (gtk_tree_model_iter_has_child(GTK_TREE_MODEL(pl->store), &iter_top)) { j = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(pl->store), &iter, &iter_top, j++)) { if (topsel || gtk_tree_selection_iter_is_selected(pl->select, &iter)) { if (foreach(pl, &iter, data)) { return; } } } } else if (topsel) { if (foreach(pl, &iter_top, data)) { return; } } } } int playlist_selection_file_types_foreach(playlist_t * pl, GtkTreeIter * iter, void * user_data) { playlist_data_t * pldata; int * i = (int *)user_data; gtk_tree_model_get(GTK_TREE_MODEL(pl->store), iter, PL_COL_DATA, &pldata, -1); if (cdda_is_cdtrack(pldata->file)) { *i = 1; } else if (!httpc_is_url(pldata->file)) { *i = 0; } return *i == 0; } /* return: 0: selection has audio file; 1: has cdda but no audio; 2: has only http or empty */ int playlist_selection_file_types(playlist_t * pl) { int type = 2; playlist_foreach_selected(pl, playlist_selection_file_types_foreach, &type); return type; } GtkTreePath * playlist_get_playing_path(playlist_t * pl) { playlist_data_t * data; GtkTreeIter iter; int i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(pl->store), &iter, NULL, i++)) { gtk_tree_model_get(GTK_TREE_MODEL(pl->store), &iter, PL_COL_DATA, &data, -1); if (IS_PL_ACTIVE(data)) { if (gtk_tree_model_iter_n_children(GTK_TREE_MODEL(pl->store), &iter) > 0) { playlist_data_t * data_child; GtkTreeIter iter_child; int j = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(pl->store), &iter_child, &iter, j++)) { gtk_tree_model_get(GTK_TREE_MODEL(pl->store), &iter_child, PL_COL_DATA, &data_child, -1); if (IS_PL_ACTIVE(data_child)) { return gtk_tree_model_get_path(GTK_TREE_MODEL(pl->store), &iter_child); } } } else { return gtk_tree_model_get_path(GTK_TREE_MODEL(pl->store), &iter); } } } return NULL; } void mark_track(playlist_t * pl, GtkTreeIter * piter) { int j, n; char * name; char counter[MAXLEN]; char tmpname[MAXLEN]; GtkTreeModel * model = GTK_TREE_MODEL(pl->store); playlist_data_t * data; gtk_tree_model_get(model, piter, PL_COL_DATA, &data, -1); if (IS_PL_ACTIVE(data)) { return; } n = gtk_tree_model_iter_n_children(model, piter); if (n) { GtkTreeIter iter_child; playlist_data_t * data_child; gtk_tree_model_get(model, piter, PL_COL_NAME, &name, -1); strncpy(tmpname, name, MAXLEN-1); j = 0; while (gtk_tree_model_iter_nth_child(model, &iter_child, piter, j++)) { gtk_tree_model_get(model, &iter_child, PL_COL_DATA, &data_child, -1); if (IS_PL_ACTIVE(data_child)) { break; } } if (j > n) { return; } sprintf(counter, _(" (%d/%d)"), j, n); strncat(tmpname, counter, MAXLEN-1); gtk_tree_store_set(pl->store, piter, PL_COL_NAME, tmpname, -1); data->ntracks = n; data->actrack = j; g_free(name); } playlist_set_active(pl->store, piter); if (gtk_tree_store_iter_depth(pl->store, piter)) { /* track node of album */ GtkTreeIter iter_parent; gtk_tree_model_iter_parent(model, &iter_parent, piter); mark_track(pl, &iter_parent); } if (options.auto_roll_to_active_track) { roll_to_active_track(pl, piter); } } void unmark_track(playlist_t * pl, GtkTreeIter * piter) { int n; GtkTreeModel * model = GTK_TREE_MODEL(pl->store); playlist_set_inactive(pl->store, piter); n = gtk_tree_model_iter_n_children(model, piter); if (n) { char name[MAXLEN]; playlist_data_t * data; gtk_tree_model_get(model, piter, PL_COL_DATA, &data, -1); snprintf(name, MAXLEN-1, "%s: %s", data->artist, data->album); gtk_tree_store_set(pl->store, piter, PL_COL_NAME, name, -1); } if (gtk_tree_store_iter_depth(pl->store, piter)) { /* track node of album */ GtkTreeIter iter_parent; gtk_tree_model_iter_parent(model, &iter_parent, piter); unmark_track(pl, &iter_parent); } } void playlist_start_playback_at_path(playlist_t * pl, GtkTreePath * path) { GtkTreeIter iter; GtkTreePath * p; gchar cmd; cue_t cue; playlist_t * plist = NULL; playlist_data_t * pldata = NULL; GtkTreeModel * model = GTK_TREE_MODEL(pl->store); if (!allow_seeks) { return; } while ((plist = playlist_get_playing()) != NULL) { playlist_set_playing(plist, 0); } playlist_set_playing(pl, 1); while ((p = playlist_get_playing_path(pl)) != NULL) { gtk_tree_model_get_iter(model, &iter, p); gtk_tree_path_free(p); unmark_track(pl, &iter); } gtk_tree_model_get_iter(model, &iter, path); if (gtk_tree_model_iter_n_children(model, &iter) > 0) { GtkTreeIter iter_child; gtk_tree_model_iter_children(model, &iter_child, &iter); mark_track(pl, &iter_child); } else { mark_track(pl, &iter); } p = playlist_get_playing_path(pl); gtk_tree_model_get_iter(model, &iter, p); gtk_tree_path_free(p); gtk_tree_model_get(model, &iter, PL_COL_DATA, &pldata, -1); cue_track_for_playback(pl->store, &iter, &cue); is_file_loaded = 1; if (options.show_sn_title) { refresh_displays(); } toggle_noeffect(PLAY, TRUE); if (is_paused) { is_paused = 0; toggle_noeffect(PAUSE, FALSE); } cmd = CMD_CUE; flush_rb_disk2gui(); rb_write(rb_gui2disk, &cmd, sizeof(char)); rb_write(rb_gui2disk, (void *)&cue, sizeof(cue_t)); try_waking_disk_thread(); } static gboolean playlist_window_close(GtkWidget * widget, GdkEvent * event, gpointer data) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(playlist_toggle), FALSE); return TRUE; } gint playlist_window_key_pressed(GtkWidget * widget, GdkEventKey * kevent) { GtkTreePath * path; GtkTreeIter iter; playlist_t * pl; if ((pl = playlist_get_current()) == NULL) { return TRUE; } switch (kevent->keyval) { case GDK_Insert: case GDK_KP_Insert: if (kevent->state & GDK_SHIFT_MASK) { /* SHIFT + Insert */ add_directory(NULL, NULL); } else { add_files(NULL, NULL); } return TRUE; case GDK_q: case GDK_Q: case GDK_Escape: if (!options.playlist_is_embedded) { playlist_window_close(NULL, NULL, NULL); } return TRUE; case GDK_F1: case GDK_i: case GDK_I: gtk_tree_view_get_cursor(GTK_TREE_VIEW(pl->view), &path, NULL); if (path && gtk_tree_model_get_iter(GTK_TREE_MODEL(pl->store), &iter, path) && !gtk_tree_model_iter_has_child(GTK_TREE_MODEL(pl->store), &iter)) { GtkTreeIter dummy; playlist_data_t * data; gtk_tree_model_get(GTK_TREE_MODEL(pl->store), &iter, PL_COL_DATA, &data, -1); playlist_data_get_display_name(fileinfo_name, data); strncpy(fileinfo_file, data->file, MAXLEN-1); fileinfo_cover = IS_PL_COVER(data); show_file_info(fileinfo_name, fileinfo_file, 0, NULL, dummy, fileinfo_cover); } if (path) { gtk_tree_path_free(path); } return TRUE; case GDK_Return: case GDK_KP_Enter: gtk_tree_view_get_cursor(GTK_TREE_VIEW(pl->view), &path, NULL); if (path) { playlist_start_playback_at_path(pl, path); gtk_tree_path_free(path); } return TRUE; case GDK_u: case GDK_U: cut__sel_cb(NULL); return TRUE; case GDK_f: case GDK_F: plist__search_cb(pl); return TRUE; case GDK_a: case GDK_A: if (kevent->state & GDK_CONTROL_MASK) { if (kevent->state & GDK_SHIFT_MASK) { sel__none_cb(NULL); } else { sel__all_cb(NULL); } } else { if (kevent->state & GDK_MOD1_MASK) { /* ALT + a */ playlist_set_current(playlist_get_playing()); show_active_position_in_playlist(playlist_get_playing()); } else { plist__roll_cb(pl); } } return TRUE; case GDK_w: case GDK_W: if (kevent->state & GDK_CONTROL_MASK) { playlist_tab_close(NULL, pl); } else { gtk_tree_view_collapse_all(GTK_TREE_VIEW(pl->view)); show_active_position_in_playlist(pl); } return TRUE; case GDK_Delete: case GDK_KP_Delete: if (kevent->state & GDK_SHIFT_MASK) { /* SHIFT + Delete */ rem__all_cb(NULL); } else if (kevent->state & GDK_CONTROL_MASK) { /* CTRL + Delete */ playlist_unlink_files(pl); } else { rem__sel_cb(NULL); } return TRUE; case GDK_t: case GDK_T: if (kevent->state & GDK_CONTROL_MASK) { if (kevent->state & GDK_SHIFT_MASK) { /* CTRL + SHIFT T */ playlist_tab_close_undo(); } else { /* CTRL + T */ playlist_tab_new(NULL); } } #ifdef HAVE_IFP else { if (kevent->state & GDK_SHIFT_MASK) { /* SHIFT T */ aifp_transfer_files(DOWNLOAD_MODE); } else { aifp_transfer_files(UPLOAD_MODE); } } #endif /* HAVE_IFP */ return TRUE; case GDK_r: case GDK_R: if (kevent->state & GDK_CONTROL_MASK) { /* CTRL + R */ tab__rename_cb(playlist_get_current()); } return TRUE; case GDK_grave: expand_collapse_album_node(pl); return TRUE; case GDK_Page_Up: if (kevent->state & GDK_CONTROL_MASK) { playlist_notebook_prev_page(); return TRUE; } break; case GDK_Page_Down: if (kevent->state & GDK_CONTROL_MASK) { playlist_notebook_next_page(); return TRUE; } break; case GDK_ISO_Left_Tab: /* it is usually mapped to SHIFT + TAB */ if (kevent->state & GDK_CONTROL_MASK) { playlist_notebook_prev_page(); } return TRUE; case GDK_Tab: if (kevent->state & GDK_CONTROL_MASK) { if (kevent->state & GDK_SHIFT_MASK) { playlist_notebook_prev_page(); } else { playlist_notebook_next_page(); } } return TRUE; case GDK_c: case GDK_C: if (kevent->state & GDK_CONTROL_MASK) { playlist_copy(playlist_get_current()); return TRUE; } break; case GDK_x: case GDK_X: if (kevent->state & GDK_CONTROL_MASK) { playlist_cut(playlist_get_current()); return TRUE; } break; case GDK_v: case GDK_V: if (kevent->state & GDK_CONTROL_MASK) { if (kevent->state & GDK_SHIFT_MASK) { playlist_paste(playlist_get_current(), 0/*after*/); } else { playlist_paste(playlist_get_current(), 1/*before*/); } return TRUE; } break; } return FALSE; } gint playlist_notebook_key_pressed(GtkWidget * widget, GdkEventKey * kevent) { if ((kevent->state & GDK_CONTROL_MASK) && (kevent->keyval == GDK_Page_Up || kevent->keyval == GDK_Page_Down)) { /* ignore default tab switching key handler */ return TRUE; } if (kevent->keyval == GDK_Tab || kevent->keyval == GDK_ISO_Left_Tab) { /* prevent focus traversal */ return TRUE; } return FALSE; } gint playlist_key_pressed(GtkWidget * widget, GdkEventKey * kevent) { if ((kevent->state & GDK_CONTROL_MASK) && (kevent->keyval == GDK_Page_Up || kevent->keyval == GDK_Page_Down)) { /* ignore default key handler for PageUp/Down when CTRL is pressed to prevent unwanted cursor motion */ return TRUE; } if (kevent->keyval == GDK_Tab || kevent->keyval == GDK_ISO_Left_Tab) { /* prevent focus traversal */ return TRUE; } return FALSE; } void playlist_menu_set_popup_sensitivity(playlist_t * pl) { int file_types = 0; int has_selection = (gtk_tree_selection_count_selected_rows(pl->select) != 0); if (has_selection) { file_types = playlist_selection_file_types(pl); } gtk_widget_set_sensitive(plist__reread_file_meta, has_selection && (file_types == 0)); gtk_widget_set_sensitive(plist__rva, has_selection && (file_types <= 1)); #ifdef HAVE_EXPORT gtk_widget_set_sensitive(plist__export, has_selection && (file_types == 0)); #endif /* HAVE_EXPORT */ #ifdef HAVE_IFP gtk_widget_set_sensitive(plist__send_songs_to_iriver, has_selection && (file_types == 0)); #endif /* HAVE_IFP */ } gint doubleclick_handler(GtkWidget * widget, GdkEventButton * event, gpointer data) { GtkTreePath * path; GtkTreeIter iter; playlist_t * pl = (playlist_t *)data; if (event->type == GDK_2BUTTON_PRESS && event->button == 1) { if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(pl->view), event->x, event->y, &path, NULL, NULL, NULL)) { playlist_start_playback_at_path(pl, path); gtk_tree_path_free(path); } return TRUE; } if (event->type == GDK_BUTTON_PRESS && event->button == 3) { if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(pl->view), event->x, event->y, &path, NULL, NULL, NULL) && gtk_tree_model_get_iter(GTK_TREE_MODEL(pl->store), &iter, path)) { if (gtk_tree_selection_count_selected_rows(pl->select) == 0) { gtk_tree_view_set_cursor(GTK_TREE_VIEW(pl->view), path, NULL, FALSE); } if (gtk_tree_model_iter_has_child(GTK_TREE_MODEL(pl->store), &iter)) { gtk_widget_set_sensitive(plist__fileinfo, FALSE); } else { playlist_data_t * data; gtk_widget_set_sensitive(plist__fileinfo, TRUE); gtk_tree_model_get(GTK_TREE_MODEL(pl->store), &iter, PL_COL_DATA, &data, -1); playlist_data_get_display_name(fileinfo_name, data); strncpy(fileinfo_file, data->file, MAXLEN-1); fileinfo_cover = IS_PL_COVER(data); } } else { gtk_widget_set_sensitive(plist__fileinfo, FALSE); } playlist_menu_set_popup_sensitivity(pl); gtk_menu_popup(GTK_MENU(plist_menu), NULL, NULL, NULL, NULL, event->button, event->time); return TRUE; } return FALSE; } static int filter(const struct dirent * de) { return de->d_name[0] != '.'; } gboolean finalize_add_to_playlist(gpointer data) { playlist_transfer_t * pt = (playlist_transfer_t *)data; pt->pl->progbar_semaphore--; if (pt->pl->progbar_semaphore != 0) { return FALSE; } if (playlist_window == NULL) { return FALSE; } if (pt->pl == playlist_get_current()) { playlist_content_changed(pt->pl); } playlist_progress_bar_hide(pt->pl); if (pt->xml_ref != NULL) { select_active_position_in_playlist(pt->pl); } return FALSE; } void playlist_data_get_display_name(char * list_str, playlist_data_t * pldata) { if (pldata->display) { strncpy(list_str, pldata->display, MAXLEN-1); } else if (pldata->artist || pldata->album || pldata->title) { make_title_string(list_str, options.title_format, pldata->artist, pldata->album, pldata->title); } else { gchar * tmp = g_filename_display_name(pldata->file); if (options.meta_use_basename_only) { char * bname = g_path_get_basename(tmp); strncpy(list_str, bname, MAXLEN-1); g_free(bname); } else { strncpy(list_str, tmp, MAXLEN-1); } g_free(tmp); if (options.meta_us_to_space) { int i; for (i = 0; list_str[i]; i++) { if (list_str[i] == '_') { list_str[i] = ' '; } } } if (options.meta_rm_extension) { char * c = NULL; if ((c = strrchr(list_str, '.')) != NULL) { *c = '\0'; } } } } gboolean add_file_to_playlist(gpointer data) { playlist_transfer_t * pt = (playlist_transfer_t *)data; GList * node; int finish = 0; AQUALUNG_MUTEX_LOCK(pt->pl->wait_mutex); if (pt->clear) { rem_all(pt->pl); pt->clear = 0; } for (node = pt->pldata_list; node; node = node->next) { GtkTreeIter iter; GtkTreePath * path; char voladj_str[32]; char duration_str[MAXLEN]; char list_str[MAXLEN]; playlist_data_t * pldata = (playlist_data_t *)node->data; pt->data_written--; if (pldata == NULL) { pt->data_written = 0; finish = 1; break; } voladj2str(pldata->voladj, voladj_str); time2time_na(pldata->duration, duration_str); if (IS_PL_TOPLEVEL(pldata)) { gtk_tree_store_append(pt->pl->store, &iter, NULL); } else { GtkTreeIter parent; int n = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(pt->pl->store), NULL); if (n == 0) { /* someone viciously cleared the list while adding tracks to album node; ignore further tracks added to this node */ playlist_data_free(pldata); continue; } gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(pt->pl->store), &parent, NULL, n-1); gtk_tree_store_append(pt->pl->store, &iter, &parent); } if (IS_PL_ALBUM_NODE(pldata)) { if (IS_PL_ACTIVE(pldata)) { snprintf(list_str, MAXLEN-1, "%s: %s (%d/%d)", pldata->artist, pldata->album, pldata->actrack, pldata->ntracks); } else { snprintf(list_str, MAXLEN-1, "%s: %s", pldata->artist, pldata->album); } } else if (IS_PL_ALBUM_CHILD(pldata)) { GtkTreeIter parent; playlist_data_t * pdata; if (gtk_tree_model_iter_parent(GTK_TREE_MODEL(pt->pl->store), &parent, &iter)) { gtk_tree_model_get(GTK_TREE_MODEL(pt->pl->store), &parent, PL_COL_DATA, &pdata, -1); if (pdata->artist && pdata->album && pldata->artist && pldata->album && pldata->title && !strcmp(pdata->artist, pldata->artist) && !strcmp(pdata->album, pldata->album)) { strncpy(list_str, pldata->title, MAXLEN-1); } else { playlist_data_get_display_name(list_str, pldata); } } } else { playlist_data_get_display_name(list_str, pldata); } gtk_tree_store_set(pt->pl->store, &iter, PL_COL_NAME, list_str, PL_COL_VADJ, IS_PL_ALBUM_NODE(pldata) ? "" : voladj_str, PL_COL_DURA, duration_str, PL_COL_COLO, IS_PL_ACTIVE(pldata) ? pl_color_active : pl_color_inactive, PL_COL_FONT, (IS_PL_ACTIVE(pldata) && options.show_active_track_name_in_bold) ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL, PL_COL_DATA, pldata, -1); if (!pt->start_playback && IS_PL_ACTIVE(pldata) && !IS_PL_ALBUM_NODE(pldata) && (path = playlist_get_playing_path(pt->pl)) != NULL) { /* deactivate item if playing path already exists */ GtkTreePath * p = gtk_tree_model_get_path(GTK_TREE_MODEL(pt->pl->store), &iter); if (gtk_tree_path_compare(path, p) != 0) { unmark_track(pt->pl, &iter); } gtk_tree_path_free(path); gtk_tree_path_free(p); } if (pt->start_playback && IS_PL_ACTIVE(pldata) && !IS_PL_ALBUM_NODE(pldata)) { GtkTreePath * p = gtk_tree_model_get_path(GTK_TREE_MODEL(pt->pl->store), &iter); GtkTreeIter parent; /* save/restore the displayed name and ntracks of an album node before/after starting playback at one of its childlen, since the album node may not yet be fully loaded */ if (gtk_tree_model_iter_parent(GTK_TREE_MODEL(pt->pl->store), &parent, &iter)) { gchar * name; unsigned short ntracks; playlist_data_t * pdata; gtk_tree_model_get(GTK_TREE_MODEL(pt->pl->store), &parent, PL_COL_NAME, &name, PL_COL_DATA, &pdata, -1); ntracks = pdata->ntracks; playlist_start_playback_at_path(pt->pl, p); gtk_tree_store_set(pt->pl->store, &parent, PL_COL_NAME, name, -1); pdata->ntracks = ntracks; g_free(name); } else { playlist_start_playback_at_path(pt->pl, p); } gtk_tree_path_free(p); pt->start_playback = 0; } } g_list_free(pt->pldata_list); pt->pldata_list = NULL; if (finish) { finalize_add_to_playlist(pt); } AQUALUNG_MUTEX_UNLOCK(pt->pl->wait_mutex); AQUALUNG_COND_SIGNAL(pt->pl->thread_wait); return FALSE; } void playlist_thread_add_to_list(playlist_transfer_t * pt, playlist_data_t * pldata) { AQUALUNG_MUTEX_LOCK(pt->pl->wait_mutex); pt->pldata_list = g_list_append(pt->pldata_list, pldata); pt->data_written++; if (pt->data_written >= pt->threshold || pldata == NULL) { if (pt->threshold < 64) { pt->threshold *= 2; } aqualung_idle_add(add_file_to_playlist, pt); while (pt->data_written > 0) { AQUALUNG_COND_WAIT(pt->pl->thread_wait, pt->pl->wait_mutex); } } AQUALUNG_MUTEX_UNLOCK(pt->pl->wait_mutex); } void * add_files_to_playlist_thread(void * arg) { playlist_transfer_t * pt = (playlist_transfer_t *)arg; GSList * node = NULL; AQUALUNG_THREAD_DETACH(); AQUALUNG_MUTEX_LOCK(pt->pl->thread_mutex); for (node = pt->list; node; node = node->next) { if (!pt->pl->thread_stop) { playlist_data_t * pldata = NULL; if ((pldata = playlist_filemeta_get((char *)node->data)) != NULL) { if (pt->start_playback) { PL_SET_FLAG(pldata, PL_FLAG_ACTIVE); } playlist_thread_add_to_list(pt, pldata); } } g_free(node->data); } playlist_thread_add_to_list(pt, NULL); g_slist_free(pt->list); AQUALUNG_MUTEX_UNLOCK(pt->pl->thread_mutex); playlist_transfer_free(pt); return NULL; } void add_files(GtkWidget * widget, gpointer data) { GSList * files = file_chooser(_("Select files"), options.playlist_is_embedded ? main_window : playlist_window, GTK_FILE_CHOOSER_ACTION_OPEN, FILE_CHOOSER_FILTER_AUDIO, TRUE, options.audiodir); if (files != NULL) { playlist_transfer_t * pt = playlist_transfer_get(PLAYLIST_ENQUEUE, NULL, 0); if (pt != NULL) { pt->list = files; playlist_progress_bar_show(pt->pl); AQUALUNG_THREAD_CREATE(pt->pl->thread_id, NULL, add_files_to_playlist_thread, pt); } } } void add_dir_to_playlist(playlist_transfer_t * pt, char * dirname) { gint i, n; struct dirent ** ent; gchar path[MAXLEN]; if (pt->pl->thread_stop) { return; } n = scandir(dirname, &ent, filter, alphasort); for (i = 0; i < n; i++) { if (pt->pl->thread_stop) { break; } snprintf(path, MAXLEN-1, "%s/%s", dirname, ent[i]->d_name); if (!g_file_test(path, G_FILE_TEST_EXISTS)) { free(ent[i]); continue; } if (g_file_test(path, G_FILE_TEST_IS_DIR)) { add_dir_to_playlist(pt, path); } else { playlist_data_t * pldata = NULL; if ((pldata = playlist_filemeta_get(path)) != NULL) { if (pt->start_playback) { PL_SET_FLAG(pldata, PL_FLAG_ACTIVE); } playlist_thread_add_to_list(pt, pldata); } } free(ent[i]); } while (i < n) { free(ent[i]); ++i; } if (n > 0) { free(ent); } } void * add_dir_to_playlist_thread(void * arg) { playlist_transfer_t * pt = (playlist_transfer_t *)arg; GSList * node = NULL; AQUALUNG_THREAD_DETACH(); AQUALUNG_MUTEX_LOCK(pt->pl->thread_mutex); for (node = pt->list; node; node = node->next) { add_dir_to_playlist(pt, (char *)node->data); g_free(node->data); } playlist_thread_add_to_list(pt, NULL); g_slist_free(pt->list); AQUALUNG_MUTEX_UNLOCK(pt->pl->thread_mutex); playlist_transfer_free(pt); return NULL; } void add_directory(GtkWidget * widget, gpointer data) { GSList * dirs = file_chooser(_("Select directory"), options.playlist_is_embedded ? main_window : playlist_window, GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, FILE_CHOOSER_FILTER_NONE, TRUE, options.audiodir); if (dirs != NULL) { playlist_transfer_t * pt = playlist_transfer_get(PLAYLIST_ENQUEUE, NULL, 0); if (pt != NULL) { pt->list = dirs; playlist_progress_bar_show(pt->pl); AQUALUNG_THREAD_CREATE(pt->pl->thread_id, NULL, add_dir_to_playlist_thread, pt); } } } gint add_url_key_press_cb(GtkWidget *widget, GdkEventKey *event, gpointer data) { if (event->keyval == GDK_Return) { gtk_dialog_response(GTK_DIALOG(widget), GTK_RESPONSE_ACCEPT); return TRUE; } return FALSE; } void add_url(GtkWidget * widget, gpointer data) { GtkWidget * dialog; GtkWidget * table; GtkWidget * hbox; GtkWidget * hbox2; GtkWidget * url_entry; GtkWidget * url_label; char url[MAXLEN]; dialog = gtk_dialog_new_with_buttons(_("Add URL"), options.playlist_is_embedded ? GTK_WINDOW(main_window) : GTK_WINDOW(playlist_window), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL); gtk_widget_set_size_request(GTK_WIDGET(dialog), 400, -1); gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER); gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_REJECT); g_signal_connect (G_OBJECT (dialog), "key_press_event", G_CALLBACK (add_url_key_press_cb), NULL); table = gtk_table_new(2, 2, FALSE); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), table, FALSE, TRUE, 2); url_label = gtk_label_new(_("URL:")); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), url_label, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(table), hbox, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 5, 5); hbox2 = gtk_hbox_new(FALSE, 0); gtk_table_attach(GTK_TABLE(table), hbox2, 1, 2, 0, 1, GTK_FILL | GTK_EXPAND, GTK_FILL, 0, 5); url_entry = gtk_entry_new(); gtk_entry_set_max_length(GTK_ENTRY(url_entry), MAXLEN - 1); gtk_entry_set_text(GTK_ENTRY(url_entry), "http://"); gtk_box_pack_start(GTK_BOX(hbox2), url_entry, TRUE, TRUE, 0); gtk_widget_grab_focus(url_entry); gtk_widget_show_all(dialog); display: url[0] = '\0'; if (aqualung_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { GtkTreeIter iter; gchar voladj_str[32]; gchar duration_str[MAXLEN]; playlist_t * pl = playlist_get_current(); playlist_data_t * data; strncpy(url, gtk_entry_get_text(GTK_ENTRY(url_entry)), MAXLEN-1); if (url[0] == '\0' || strstr(url, "http://") != url || strlen(url) <= strlen("http://")) { gtk_widget_grab_focus(url_entry); goto display; } if ((data = playlist_data_new()) == NULL) { return; } data->file = strdup(url); data->duration = 0.0f; data->voladj = options.rva_no_rva_voladj; voladj2str(data->voladj, voladj_str); time2time_na(data->duration, duration_str); gtk_tree_store_append(pl->store, &iter, NULL); gtk_tree_store_set(pl->store, &iter, PL_COL_NAME, url, PL_COL_VADJ, voladj_str, PL_COL_DURA, duration_str, PL_COL_COLO, pl_color_inactive, PL_COL_FONT, PANGO_WEIGHT_NORMAL, PL_COL_DATA, data, -1); playlist_content_changed(pl); } gtk_widget_destroy(dialog); } void plist__save_cb(gpointer data) { GSList * file; playlist_t * pl; if ((pl = playlist_get_current()) == NULL) { return; } file = file_chooser(_("Please specify the file to save the playlist to."), options.playlist_is_embedded ? main_window : playlist_window, GTK_FILE_CHOOSER_ACTION_SAVE, FILE_CHOOSER_FILTER_NONE, FALSE, options.plistdir); if (file != NULL) { if (g_str_has_suffix((gchar *)file->data, ".m3u")) { playlist_save_m3u(pl, (char *)file->data); } else { playlist_save(pl, (char *)file->data); } g_free(file->data); g_slist_free(file); } } void plist__save_all_cb(gpointer data) { GSList * file; playlist_t * pl; if ((pl = playlist_get_current()) == NULL) { return; } file = file_chooser(_("Please specify the file to save the playlist to."), options.playlist_is_embedded ? main_window : playlist_window, GTK_FILE_CHOOSER_ACTION_SAVE, FILE_CHOOSER_FILTER_NONE, FALSE, options.plistdir); if (file != NULL) { playlist_save_all((char *)file->data); g_free(file->data); g_slist_free(file); } } playlist_transfer_t * playlist_transfer_get(int mode, char * tab_name, int start_playback) { playlist_t * pl = NULL; playlist_transfer_t * pt = NULL; if (mode == PLAYLIST_LOAD_TAB) { pl = playlist_tab_new(tab_name); pt = playlist_transfer_new(pl); } else { if (tab_name == NULL) { pl = playlist_get_current(); } else { pl = playlist_get_by_name(tab_name); } if (pl == NULL) { pl = playlist_tab_new(tab_name); } pt = playlist_transfer_new(pl); } if (mode == PLAYLIST_LOAD) { pt->clear = 1; } pt->start_playback = start_playback; return pt; } void playlist_load(GSList * list, int mode, char * tab_name, int start_playback) { GSList * node; playlist_t * pl = NULL; playlist_transfer_t * pt = NULL; char fullname[MAXLEN]; int type; for (node = list; node; node = node->next) { normalize_filename((char *)node->data, fullname); type = playlist_get_type(fullname); if (type != PLAYLIST_XML_MULTI) { /* content goes to the same playlist */ if (pl == NULL) { pt = playlist_transfer_get(mode, tab_name, start_playback); pl = pt->pl; start_playback = 0; } else { pt = playlist_transfer_new(pl); } } switch (type) { case PLAYLIST_INVALID: /* not a playlist, trying to load as audio file */ pt->list = g_slist_append(NULL, strdup(fullname)); playlist_progress_bar_show(pt->pl); if (g_file_test(fullname, G_FILE_TEST_IS_DIR)) { AQUALUNG_THREAD_CREATE(pt->pl->thread_id, NULL, add_dir_to_playlist_thread, pt); } else { AQUALUNG_THREAD_CREATE(pt->pl->thread_id, NULL, add_files_to_playlist_thread, pt); } break; case PLAYLIST_XML_MULTI: playlist_load_xml_multi(fullname, start_playback); start_playback = 0; break; case PLAYLIST_XML_SINGLE: playlist_load_xml_single(fullname, pt); break; case PLAYLIST_M3U: playlist_progress_bar_show(pt->pl); pt->filename = strdup(fullname); AQUALUNG_THREAD_CREATE(pt->pl->thread_id, NULL, playlist_load_m3u_thread, pt); break; case PLAYLIST_PLS: playlist_progress_bar_show(pt->pl); pt->filename = strdup(fullname); AQUALUNG_THREAD_CREATE(pt->pl->thread_id, NULL, playlist_load_pls_thread, pt); break; } free(node->data); } g_slist_free(list); } void playlist_load_dialog(int mode) { GSList * files; files = file_chooser(_("Please specify the file to load the playlist from."), options.playlist_is_embedded ? main_window : playlist_window, GTK_FILE_CHOOSER_ACTION_OPEN, FILE_CHOOSER_FILTER_PLAYLIST, FALSE, options.plistdir); if (files != NULL) { playlist_load(files, mode, NULL, 0); } } void plist__load_cb(gpointer data) { playlist_load_dialog(PLAYLIST_LOAD); } void plist__enqueue_cb(gpointer data) { playlist_load_dialog(PLAYLIST_ENQUEUE); } void plist__load_tab_cb(gpointer data) { playlist_load_dialog(PLAYLIST_LOAD_TAB); } int plist_setup_vol_foreach(playlist_t * pl, GtkTreeIter * iter, void * data) { volume_t * vol = (volume_t *)data; playlist_data_t * pldata; gtk_tree_model_get(GTK_TREE_MODEL(pl->store), iter, PL_COL_DATA, &pldata, -1); if (!httpc_is_url(pldata->file)) { volume_push(vol, pldata->file, *iter); } return 0; } void plist_setup_vol_calc(playlist_t * pl, int type) { volume_t * vol; if (!options.rva_is_enabled) { int ret = message_dialog(_("Warning"), options.playlist_is_embedded ? main_window : playlist_window, GTK_MESSAGE_WARNING, GTK_BUTTONS_YES_NO, NULL, _("Playback RVA is currently disabled.\n" "Do you want to enable it now?")); if (ret != GTK_RESPONSE_YES) { return; } options.rva_is_enabled = 1; } if ((vol = volume_new(pl->store, type)) == NULL) { return; } playlist_foreach_selected(pl, plist_setup_vol_foreach, vol); volume_start(vol); } void plist__rva_separate_cb(gpointer data) { playlist_t * pl; if ((pl = playlist_get_current()) == NULL) { return; } plist_setup_vol_calc(pl, VOLUME_SEPARATE); } void plist__rva_average_cb(gpointer data) { playlist_t * pl; if ((pl = playlist_get_current()) == NULL) { return; } plist_setup_vol_calc(pl, VOLUME_AVERAGE); } int plist__reread_file_meta_foreach(playlist_t * pl, GtkTreeIter * iter, void * user_data) { GtkTreeIter parent; int name_set = 0; char voladj_str[32]; char duration_str[MAXLEN]; playlist_data_t * data; playlist_data_t * tmp; gtk_tree_model_get(GTK_TREE_MODEL(pl->store), iter, PL_COL_DATA, &data, -1); if (!g_file_test(data->file, G_FILE_TEST_EXISTS)) { return 0; } if ((tmp = playlist_filemeta_get(data->file)) == NULL) { fprintf(stderr, "plist__reread_file_meta_foreach(): " "playlist_filemeta_get() returned NULL\n"); return 0; } free_strdup(&data->artist, tmp->artist); free_strdup(&data->album, tmp->album); free_strdup(&data->title, tmp->title); free_strdup(&data->display, tmp->display); data->voladj = tmp->voladj; data->duration = tmp->duration; data->size = tmp->size; playlist_data_free(tmp); voladj2str(data->voladj, voladj_str); time2time_na(data->duration, duration_str); gtk_tree_store_set(pl->store, iter, PL_COL_VADJ, voladj_str, PL_COL_DURA, duration_str, -1); if (gtk_tree_model_iter_parent(GTK_TREE_MODEL(pl->store), &parent, iter)) { playlist_data_t * pdata; gtk_tree_model_get(GTK_TREE_MODEL(pl->store), &parent, PL_COL_DATA, &pdata, -1); if (pdata->artist && pdata->album && data->artist && data->album && data->title && !strcmp(pdata->artist, data->artist) && !strcmp(pdata->album, data->album)) { gtk_tree_store_set(pl->store, iter, PL_COL_NAME, data->title, -1); name_set = 1; } } if (!name_set) { char list_str[MAXLEN]; playlist_data_get_display_name(list_str, data); gtk_tree_store_set(pl->store, iter, PL_COL_NAME, list_str, -1); } return 0; } void plist__reread_file_meta_cb(gpointer data) { GtkTreeIter iter; GtkTreeIter iter_child; gint i = 0; gint j = 0; gint reread = 0; playlist_t * pl; if ((pl = playlist_get_current()) == NULL) { return; } playlist_foreach_selected(pl, plist__reread_file_meta_foreach, NULL); i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(pl->store), &iter, NULL, i++)) { if (gtk_tree_model_iter_has_child(GTK_TREE_MODEL(pl->store), &iter)) { reread = 0; if (gtk_tree_selection_iter_is_selected(pl->select, &iter)) { reread = 1; } else { j = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(pl->store), &iter_child, &iter, j++)) { if (gtk_tree_selection_iter_is_selected(pl->select, &iter_child)) { reread = 1; break; } } } if (reread) { recalc_album_node(pl, &iter); } } } playlist_content_changed(pl); } #ifdef HAVE_EXPORT int plist__export_foreach(playlist_t * pl, GtkTreeIter * iter, void * data) { export_t * export = (export_t *)data; playlist_data_t * pldata; file_decoder_t * fdec; char artist[MAXLEN]; char album[MAXLEN]; char title[MAXLEN]; int year = 0; int no = 0; artist[0] = '\0'; album[0] = '\0'; title[0] = '\0'; gtk_tree_model_get(GTK_TREE_MODEL(pl->store), iter, PL_COL_DATA, &pldata, -1); if (!g_file_test(pldata->file, G_FILE_TEST_EXISTS)) { return 0; } fdec = file_decoder_new(); if (fdec == NULL) { fprintf(stderr, "plist__export_foreach: file_decoder_new() failed\n"); return 0; } if (file_decoder_open(fdec, pldata->file) == 0) { char * tmp; if (pldata->artist) { strcpy(artist, pldata->artist); } else if (metadata_get_artist(fdec->meta, &tmp)) { strncpy(artist, tmp, MAXLEN-1); } if (pldata->album) { strcpy(album, pldata->album); } else if (metadata_get_album(fdec->meta, &tmp)) { strncpy(album, tmp, MAXLEN-1); } if (pldata->title) { strcpy(title, pldata->title); } else if (metadata_get_title(fdec->meta, &tmp)) { strncpy(title, tmp, MAXLEN-1); } if (metadata_get_date(fdec->meta, &tmp)) { year = atoi(tmp); } if (!metadata_get_tracknum(fdec->meta, &no)) { GtkTreePath * path = gtk_tree_model_get_path(GTK_TREE_MODEL(pl->store), iter); int depth = gtk_tree_path_get_depth(path); gint * indices = gtk_tree_path_get_indices(path); no = indices[depth-1] + 1; gtk_tree_path_free(path); } file_decoder_close(fdec); } file_decoder_delete(fdec); export_append_item(export, pldata->file, artist, album, title, year, no); return 0; } void plist__export_cb(gpointer data) { export_t * export; playlist_t * pl; if ((pl = playlist_get_current()) == NULL) { return; } if ((export = export_new()) == NULL) { return; } playlist_foreach_selected(pl, plist__export_foreach, export); export_start(export); } #endif /* HAVE_EXPORT */ #ifdef HAVE_IFP void plist__send_songs_to_iriver_cb(gpointer data) { aifp_transfer_files(UPLOAD_MODE); } #endif /* HAVE_IFP */ void plist__fileinfo_cb(gpointer user_data) { GtkTreeIter dummy; show_file_info(fileinfo_name, fileinfo_file, 0, NULL, dummy, fileinfo_cover); } void plist__search_cb(gpointer data) { search_playlist_dialog(); } void plist__roll_cb(gpointer data) { playlist_t * pl; if ((pl = playlist_get_current()) == NULL) { return; } show_active_position_in_playlist_toggle(pl); } static gboolean add_cb(GtkWidget * widget, GdkEvent * event) { if (event->type == GDK_BUTTON_PRESS) { GdkEventButton * bevent = (GdkEventButton *) event; if (bevent->button == 3) { gtk_menu_popup(GTK_MENU(add_menu), NULL, NULL, NULL, NULL, bevent->button, bevent->time); return TRUE; } return FALSE; } return FALSE; } static gboolean sel_cb(GtkWidget * widget, GdkEvent * event) { if (event->type == GDK_BUTTON_PRESS) { GdkEventButton * bevent = (GdkEventButton *) event; if (bevent->button == 3) { gtk_menu_popup(GTK_MENU(sel_menu), NULL, NULL, NULL, NULL, bevent->button, bevent->time); return TRUE; } return FALSE; } return FALSE; } static gboolean rem_cb(GtkWidget * widget, GdkEvent * event) { if (event->type == GDK_BUTTON_PRESS) { GdkEventButton * bevent = (GdkEventButton *) event; if (bevent->button == 3) { gtk_menu_popup(GTK_MENU(rem_menu), NULL, NULL, NULL, NULL, bevent->button, bevent->time); return TRUE; } return FALSE; } return FALSE; } playlist_data_t * playlist_filemeta_get(char * filename) { playlist_data_t * data; file_decoder_t * fdec; struct stat statbuf; char * tmp; if ((data = playlist_data_new()) == NULL) { return NULL; } fdec = file_decoder_new(); if (fdec == NULL) { fprintf(stderr, "playlist_filemeta_get: file_decoder_new() failed\n"); playlist_data_free(data); return NULL; } if (file_decoder_open(fdec, filename) != 0) { file_decoder_delete(fdec); playlist_data_free(data); return NULL; } if (g_stat(data->file, &statbuf) != -1) { data->size = statbuf.st_size; } data->duration = (float)fdec->fileinfo.total_samples / fdec->fileinfo.sample_rate; if (options.rva_is_enabled) { if (!metadata_get_rva(fdec->meta, &data->voladj)) { data->voladj = options.rva_no_rva_voladj; } } else { data->voladj = 0.0f; } if (metadata_get_artist(fdec->meta, &tmp) && !is_all_wspace(tmp)) { free_strdup(&data->artist, tmp); } if (metadata_get_album(fdec->meta, &tmp) && !is_all_wspace(tmp)) { free_strdup(&data->album, tmp); } if (metadata_get_title(fdec->meta, &tmp) && !is_all_wspace(tmp)) { free_strdup(&data->title, tmp); } #ifdef HAVE_LUA data->display = extended_title_format(fdec); #endif /* HAVE_LUA */ file_decoder_close(fdec); file_decoder_delete(fdec); data->file = strdup(filename); return data; } void add__files_cb(gpointer data) { add_files(NULL, NULL); } void add__dir_cb(gpointer data) { add_directory(NULL, NULL); } void add__url_cb(gpointer data) { add_url(NULL, NULL); } void select_all(GtkWidget * widget, gpointer data) { playlist_t * pl = playlist_get_current(); if (pl != NULL) { gtk_tree_selection_select_all(pl->select); } } void sel__all_cb(gpointer data) { select_all(NULL, data); } void sel__none_cb(gpointer data) { playlist_t * pl; if ((pl = playlist_get_current()) != NULL) { gtk_tree_selection_unselect_all(pl->select); } } void sel__inv_foreach(GtkTreePath * path, gpointer data) { gtk_tree_selection_unselect_path((GtkTreeSelection *)data, path); gtk_tree_path_free(path); } void sel__inv_cb(gpointer data) { GList * list = NULL; playlist_t * pl = NULL; if ((pl = playlist_get_current()) == NULL) { return; } list = gtk_tree_selection_get_selected_rows(pl->select, NULL); g_signal_handlers_block_by_func(G_OBJECT(pl->select), playlist_selection_changed_cb, pl); gtk_tree_selection_select_all(pl->select); g_list_foreach(list, (GFunc)sel__inv_foreach, pl->select); g_list_free(list); g_signal_handlers_unblock_by_func(G_OBJECT(pl->select), playlist_selection_changed_cb, pl); playlist_selection_changed(pl); } void rem_all(playlist_t * pl) { g_signal_handlers_block_by_func(G_OBJECT(pl->select), playlist_selection_changed_cb, pl); playlist_clear(pl->store); g_signal_handlers_unblock_by_func(G_OBJECT(pl->select), playlist_selection_changed_cb, pl); if (pl == playlist_get_current()) { playlist_selection_changed(pl); playlist_content_changed(pl); } } void rem__all_cb(gpointer data) { playlist_t * pl; if ((pl = playlist_get_current()) == NULL) { return; } rem_all(pl); } void rem__sel_cb(gpointer data) { GtkTreeModel * model; GtkTreeIter iter; gint i = 0; playlist_t * pl; GtkTreePath * path = NULL; if (data != NULL) { pl = (playlist_t *)data; } else if ((pl = playlist_get_current()) == NULL) { return; } g_signal_handlers_block_by_func(G_OBJECT(pl->select), playlist_selection_changed_cb, pl); model = GTK_TREE_MODEL(pl->store); while (gtk_tree_model_iter_nth_child(model, &iter, NULL, i++)) { if (gtk_tree_selection_iter_is_selected(pl->select, &iter)) { if (path == NULL) { path = gtk_tree_model_get_path(model, &iter); } playlist_remove_track(pl->store, &iter); i--; continue; } if (gtk_tree_model_iter_n_children(model, &iter) == 0) { continue; } if (all_tracks_selected(pl, &iter)) { if (path == NULL) { path = gtk_tree_model_get_path(model, &iter); } playlist_remove_track(pl->store, &iter); i--; } else { int j = 0; int recalc = 0; GtkTreeIter iter_child; while (gtk_tree_model_iter_nth_child(model, &iter_child, &iter, j++)) { if (gtk_tree_selection_iter_is_selected(pl->select, &iter_child)) { if (path == NULL) { path = gtk_tree_model_get_path(model, &iter_child); } playlist_remove_track(pl->store, &iter_child); recalc = 1; j--; } } if (recalc) { recalc_album_node(pl, &iter); } } } if (path != NULL) { if (gtk_tree_model_get_iter(model, &iter, path)) { set_cursor_in_playlist(pl, &iter, TRUE); } else { if (gtk_tree_path_get_depth(path) == 1) { int n = gtk_tree_model_iter_n_children(model, NULL); if (n > 0) { gtk_tree_model_iter_nth_child(model, &iter, NULL, n-1); set_cursor_in_playlist(pl, &iter, TRUE); } } else { GtkTreeIter iter_child; gtk_tree_path_up(path); gtk_tree_model_get_iter(model, &iter, path); gtk_tree_model_iter_nth_child(model, &iter_child, &iter, gtk_tree_model_iter_n_children(model, &iter)-1); set_cursor_in_playlist(pl, &iter_child, TRUE); } } gtk_tree_path_free(path); } g_signal_handlers_unblock_by_func(G_OBJECT(pl->select), playlist_selection_changed_cb, pl); playlist_content_changed(pl); playlist_selection_changed(pl); } int rem__dead_skip(char * filename) { return (filename != NULL && !cdda_is_cdtrack(filename) && !httpc_is_url(filename) && (g_file_test(filename, G_FILE_TEST_IS_REGULAR) == FALSE)); } void rem__dead_cb(gpointer user_data) { GtkTreeIter iter; gint i = 0; playlist_t * pl; playlist_data_t * data; if ((pl = playlist_get_current()) == NULL) { return; } while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(pl->store), &iter, NULL, i++)) { GtkTreeIter iter_child; gint j = 0; gtk_tree_model_get(GTK_TREE_MODEL(pl->store), &iter, PL_COL_DATA, &data, -1); gint n = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(pl->store), &iter); if (n == 0 && rem__dead_skip(data->file)) { playlist_remove_track(pl->store, &iter); --i; continue; } if (n) { while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(pl->store), &iter_child, &iter, j++)) { gtk_tree_model_get(GTK_TREE_MODEL(pl->store), &iter_child, PL_COL_DATA, &data, -1); if (rem__dead_skip(data->file)) { playlist_remove_track(pl->store, &iter_child); --j; } } /* remove album node if empty */ if (gtk_tree_model_iter_n_children(GTK_TREE_MODEL(pl->store), &iter) == 0) { playlist_remove_track(pl->store, &iter); --i; } else { recalc_album_node(pl, &iter); } } } playlist_content_changed(pl); } void remove_sel(GtkWidget * widget, gpointer data) { rem__sel_cb(data); } /* playlist item is selected -> keep, else -> remove * ret: 0 if kept, 1 if removed track */ int cut_track_item(playlist_t * pl, GtkTreeIter * piter) { if (!gtk_tree_selection_iter_is_selected(pl->select, piter)) { playlist_remove_track(pl->store, piter); return 1; } return 0; } /* ret: 1 if at least one of album node's children are selected; else 0 */ int any_tracks_selected(playlist_t * pl, GtkTreeIter * piter) { gint j = 0; GtkTreeIter iter_child; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(pl->store), &iter_child, piter, j++)) { if (gtk_tree_selection_iter_is_selected(pl->select, &iter_child)) { return 1; } } return 0; } /* cut selected callback */ void cut__sel_cb(gpointer data) { GtkTreeIter iter; gint i = 0; playlist_t * pl; if ((pl = playlist_get_current()) == NULL) { return; } while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(pl->store), &iter, NULL, i++)) { gint n = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(pl->store), &iter); if (n) { /* album node */ if (any_tracks_selected(pl, &iter)) { gint j = 0; GtkTreeIter iter_child; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(pl->store), &iter_child, &iter, j++)) { j -= cut_track_item(pl, &iter_child); } recalc_album_node(pl, &iter); } else { i -= cut_track_item(pl, &iter); } } else { /* track node */ i -= cut_track_item(pl, &iter); } } gtk_tree_selection_unselect_all(pl->select); playlist_content_changed(pl); } void playlist_reorder_columns_foreach(gpointer data, gpointer user_data) { playlist_t * pl = (playlist_t *)data; int * order = (int *)user_data; GtkTreeViewColumn * cols[3]; int i; cols[0] = pl->track_column; cols[1] = pl->rva_column; cols[2] = pl->length_column; for (i = 2; i >= 0; i--) { gtk_tree_view_move_column_after(GTK_TREE_VIEW(pl->view), cols[order[i]], NULL); } gtk_tree_view_column_set_visible(GTK_TREE_VIEW_COLUMN(pl->rva_column), options.show_rva_in_playlist); gtk_tree_view_column_set_visible(GTK_TREE_VIEW_COLUMN(pl->length_column), options.show_length_in_playlist); gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(pl->view), options.enable_pl_rules_hint); } void playlist_reorder_columns_all(int * order) { g_list_foreach(playlists, playlist_reorder_columns_foreach, order); if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(playlist_notebook)) == 1) { gtk_notebook_set_show_tabs(GTK_NOTEBOOK(playlist_notebook), options.playlist_always_show_tabs); } } void playlist_stats_set_busy() { gtk_label_set_text(GTK_LABEL(statusbar_total), _("counting...")); } void playlist_child_stats(playlist_t * pl, GtkTreeIter * iter, int * ntrack, float * length, double * size, int selected) { int j = 0; GtkTreeIter iter_child; playlist_data_t * data; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(pl->store), &iter_child, iter, j++)) { if (!selected || gtk_tree_selection_iter_is_selected(pl->select, &iter_child)) { gtk_tree_model_get(GTK_TREE_MODEL(pl->store), &iter_child, PL_COL_DATA, &data, -1); if (data->size == 0) { struct stat statbuf; if (g_stat(data->file, &statbuf) != -1) { data->size = statbuf.st_size; } } *size += data->size / 1024.0; *length += data->duration; (*ntrack)++; } } } /* if selected == true -> stats for selected tracks; else: all tracks */ void playlist_stats(playlist_t * pl, int selected) { GtkTreeIter iter; int i = 0; int ntrack = 0; float length = 0; double size = 0; char str[MAXLEN]; char length_str[MAXLEN]; char tmp[MAXLEN]; playlist_data_t * data; if (!options.enable_playlist_statusbar) { return; } while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(pl->store), &iter, NULL, i++)) { gint n = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(pl->store), &iter); if (n > 0) { if (gtk_tree_selection_iter_is_selected(pl->select, &iter)) { playlist_child_stats(pl, &iter, &ntrack, &length, &size, 0/*false*/); } else { playlist_child_stats(pl, &iter, &ntrack, &length, &size, selected); } } else { if (!selected || gtk_tree_selection_iter_is_selected(pl->select, &iter)) { gtk_tree_model_get(GTK_TREE_MODEL(pl->store), &iter, PL_COL_DATA, &data, -1); if (data->size == 0) { struct stat statbuf; if (g_stat(data->file, &statbuf) != -1) { data->size = statbuf.st_size; } } size += data->size / 1024.0; length += data->duration; ntrack++; } } } sprintf(str, " %d %s ", ntrack, (ntrack == 1) ? _("track") : _("tracks")); if (length > 0.0f || ntrack == 0) { time2time(length, length_str); sprintf(tmp, " [%s] ", length_str); strcat(str, tmp); } if (options.pl_statusbar_show_size) { if (size > 1024 * 1024) { sprintf(tmp, " (%.1f GB) ", size / (1024 * 1024)); strcat(str, tmp); } else if (size > (1 << 10)){ sprintf(tmp, " (%.1f MB) ", size / 1024); strcat(str, tmp); } else if (size > 0 || ntrack == 0) { sprintf(tmp, " (%.1f KB) ", size); strcat(str, tmp); } } if (selected) { gtk_label_set_text(GTK_LABEL(statusbar_selected), str); } else { gtk_label_set_text(GTK_LABEL(statusbar_total), str); } } void recalc_album_node(playlist_t * pl, GtkTreeIter * iter) { gint ntrack = 0; gfloat length = 0; double size = 0.0; gchar time[MAXLEN]; playlist_data_t * data; gtk_tree_model_get(GTK_TREE_MODEL(pl->store), iter, PL_COL_DATA, &data, -1); playlist_child_stats(pl, iter, &ntrack, &length, &size, 0/*false*/); time2time(length, time); gtk_tree_store_set(pl->store, iter, PL_COL_DURA, time, -1); data->duration = length; if (IS_PL_ACTIVE(data)) { unmark_track(pl, iter); mark_track(pl, iter); } } void playlist_selection_changed(playlist_t * pl) { playlist_stats(pl, 1/* true */); } void playlist_content_changed(playlist_t * pl) { if (pl->progbar_semaphore == 0 && pl->ms_semaphore == 0) { playlist_stats(pl, 0/*false*/); playlist_dirty = 1; } else { playlist_stats_set_busy(); } } void playlist_selection_changed_cb(GtkTreeSelection * select, gpointer data) { playlist_t * pl = (playlist_t *)data; if (pl == playlist_get_current()) { playlist_selection_changed(pl); } } void playlist_drag_data_get(GtkWidget * widget, GdkDragContext * drag_context, GtkSelectionData * data, guint info, guint time, gpointer user_data) { char tmp[32]; sprintf(tmp, "%p", user_data); gtk_selection_data_set(data, data->target, 8, (guchar *)tmp, strlen(tmp)); } void playlist_perform_drag(playlist_t * spl, GtkTreeIter * siter, GtkTreePath * spath, playlist_t * tpl, GtkTreeIter * titer, GtkTreePath * tpath) { GtkTreeIter sparent; GtkTreeIter tparent; int recalc_sparent = 0; int recalc_tparent = 0; gint cmp = 2/*append*/; if (tpath != NULL) { cmp = gtk_tree_path_compare(spath, tpath); } if (spl == tpl && cmp == 0) { return; } if (titer && tpath && gtk_tree_model_iter_has_child(GTK_TREE_MODEL(spl->store), siter) && !gtk_tree_model_iter_has_child(GTK_TREE_MODEL(tpl->store), titer) && gtk_tree_path_get_depth(tpath) == 2) { return; } if (gtk_tree_model_iter_parent(GTK_TREE_MODEL(spl->store), &sparent, siter)) { recalc_sparent = 1; } if (titer && gtk_tree_model_iter_parent(GTK_TREE_MODEL(tpl->store), &tparent, titer)) { recalc_tparent = 1; } playlist_node_deep_copy(spl->store, siter, tpl->store, titer, titer ? (cmp == 1) : 2); gtk_tree_store_remove(spl->store, siter); if (tpath) { gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW (tpl->view), tpath, NULL, FALSE, 0, 0); } if (recalc_sparent) { if (gtk_tree_model_iter_has_child(GTK_TREE_MODEL(spl->store), &sparent)) { recalc_album_node(spl, &sparent); unmark_track(spl, &sparent); mark_track(spl, &sparent); } else { gtk_tree_store_remove(spl->store, &sparent); } } if (recalc_tparent) { recalc_album_node(tpl, &tparent); unmark_track(tpl, &tparent); mark_track(tpl, &tparent); } playlist_content_changed(tpl); } void playlist_remove_scroll_tags() { if (playlist_scroll_up_tag > 0) { g_source_remove(playlist_scroll_up_tag); playlist_scroll_up_tag = -1; } if (playlist_scroll_dn_tag > 0) { g_source_remove(playlist_scroll_dn_tag); playlist_scroll_dn_tag = -1; } } gint playlist_drag_data_received(GtkWidget * widget, GdkDragContext * drag_context, gint x, gint y, GtkSelectionData * data, guint info, guint time, gpointer user_data) { playlist_t * tpl = (playlist_t *)user_data; if (info == 0) { /* drag and drop inside or between playlists */ GtkTreeIter siter; GtkTreeIter titer; GtkTreePath * spath = NULL; GtkTreePath * tpath = NULL; playlist_t * spl = NULL; sscanf((char *)data->data, "%p", &spl); gtk_tree_selection_set_mode(spl->select, GTK_SELECTION_SINGLE); if (gtk_tree_selection_get_selected(spl->select, NULL, &siter)) { spath = gtk_tree_model_get_path(GTK_TREE_MODEL(spl->store), &siter); if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(tpl->view), x, y, &tpath, NULL, NULL, NULL)) { gtk_tree_model_get_iter(GTK_TREE_MODEL(tpl->store), &titer, tpath); playlist_perform_drag(spl, &siter, spath, tpl, &titer, tpath); } else { playlist_perform_drag(spl, &siter, spath, tpl, NULL, NULL); } } if (spath) { gtk_tree_path_free(spath); } if (tpath) { gtk_tree_path_free(tpath); } gtk_tree_selection_set_mode(spl->select, GTK_SELECTION_MULTIPLE); } else if (info == 1) { /* drag and drop from music store to playlist */ GtkTreePath * path = NULL; GtkTreeIter * piter = NULL; GtkTreeIter ms_iter; GtkTreeIter pl_iter; GtkTreeIter parent; GtkTreeModel * model; if (!gtk_tree_selection_get_selected(music_select, &model, &ms_iter)) { return FALSE; } if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(tpl->view), x, y, &path, NULL, NULL, NULL)) { if (!music_store_iter_is_track(&ms_iter)) { while (gtk_tree_path_get_depth(path) > 1) { gtk_tree_path_up(path); } } gtk_tree_model_get_iter(GTK_TREE_MODEL(tpl->store), &pl_iter, path); piter = &pl_iter; } music_store_iter_addlist_defmode(&ms_iter, piter, 0/*new_tab*/); if (piter && gtk_tree_model_iter_parent(GTK_TREE_MODEL(tpl->store), &parent, piter) && music_store_iter_is_track(&ms_iter)) { recalc_album_node(tpl, &parent); unmark_track(tpl, &parent); mark_track(tpl, &parent); } if (path) { gtk_tree_path_free(path); } } else if (info == 2) { /* drag and drop from external app */ GSList * list = NULL; gchar ** uri_list; gchar * str = NULL; int i; char file[MAXLEN]; for (i = 0; *((gchar *)data->data + i); i++) { if (*((gchar *)data->data + i) == '\r') { *((gchar *)data->data + i) = '\n'; } } uri_list = g_strsplit((gchar *)data->data, "\n", 0); for (i = 0; uri_list[i]; i++) { if (*(uri_list[i]) == '\0') { continue; } if ((str = g_filename_from_uri(uri_list[i], NULL, NULL)) != NULL) { strncpy(file, str, MAXLEN-1); g_free(str); } else { int off = 0; if (strstr(uri_list[i], "file:") == uri_list[i] || strstr(uri_list[i], "FILE:") == uri_list[i]) { off = 5; } while (uri_list[i][off] == '/' && uri_list[i][off+1] == '/') { off++; } strncpy(file, uri_list[i] + off, MAXLEN-1); } if ((str = g_filename_from_utf8(file, -1, NULL, NULL, NULL)) != NULL) { strncpy(file, str, MAXLEN-1); g_free(str); } if (g_file_test(file, G_FILE_TEST_EXISTS) || httpc_is_url(file)) { list = g_slist_append(list, strdup(file)); } } if (list != NULL) { playlist_load(list, PLAYLIST_ENQUEUE, NULL, 0); } g_strfreev(uri_list); playlist_remove_scroll_tags(); } return FALSE; } gint playlist_scroll_up(gpointer data) { playlist_t * pl = (playlist_t *)data; #if (GTK_CHECK_VERSION(2,8,0)) gboolean dummy; GtkRange * range = GTK_RANGE(gtk_scrolled_window_get_vscrollbar(GTK_SCROLLED_WINDOW(pl->scroll))); g_signal_emit_by_name(G_OBJECT(range), "move-slider", GTK_SCROLL_STEP_UP, &dummy); #else g_signal_emit_by_name(G_OBJECT(pl->scroll), "scroll-child", GTK_SCROLL_STEP_BACKWARD, FALSE/*vertical*/, NULL); #endif /* GTK_CHECK_VERSION */ return TRUE; } gint playlist_scroll_dn(gpointer data) { playlist_t * pl = (playlist_t *)data; #if (GTK_CHECK_VERSION(2,8,0)) gboolean dummy; GtkRange * range = GTK_RANGE(gtk_scrolled_window_get_vscrollbar(GTK_SCROLLED_WINDOW(pl->scroll))); g_signal_emit_by_name(G_OBJECT(range), "move-slider", GTK_SCROLL_STEP_DOWN, &dummy); #else g_signal_emit_by_name(G_OBJECT(pl->scroll), "scroll-child", GTK_SCROLL_STEP_FORWARD, FALSE/*vertical*/, NULL); #endif /* GTK_CHECK_VERSION */ return TRUE; } void playlist_drag_leave(GtkWidget * widget, GdkDragContext * drag_context, guint time, gpointer data) { playlist_remove_scroll_tags(); } gboolean playlist_drag_motion(GtkWidget * widget, GdkDragContext * context, gint x, gint y, guint time, gpointer data) { if (y < 30) { if (playlist_scroll_up_tag == -1) { playlist_scroll_up_tag = aqualung_timeout_add(100, playlist_scroll_up, data); } } else { if (playlist_scroll_up_tag > 0) { g_source_remove(playlist_scroll_up_tag); playlist_scroll_up_tag = -1; } } if (y > widget->allocation.height - 30) { if (playlist_scroll_dn_tag == -1) { playlist_scroll_dn_tag = aqualung_timeout_add(100, playlist_scroll_dn, data); } } else { if (playlist_scroll_dn_tag > 0) { g_source_remove(playlist_scroll_dn_tag); playlist_scroll_dn_tag = -1; } } return TRUE; } void playlist_drag_end(GtkWidget * widget, GdkDragContext * drag_context, gpointer data) { playlist_remove_scroll_tags(); } void playlist_rename(playlist_t * pl, char * name) { if (name != NULL) { strncpy(pl->name, name, MAXLEN-1); pl->name_set = 1; playlist_set_markup(pl); } } void playlist_notebook_prev_page(void) { if (gtk_notebook_get_current_page(GTK_NOTEBOOK(playlist_notebook)) == 0) { gtk_notebook_set_current_page(GTK_NOTEBOOK(playlist_notebook), -1); } else { gtk_notebook_prev_page(GTK_NOTEBOOK(playlist_notebook)); } } void playlist_notebook_next_page(void) { if (gtk_notebook_get_current_page(GTK_NOTEBOOK(playlist_notebook)) == gtk_notebook_get_n_pages(GTK_NOTEBOOK(playlist_notebook)) - 1) { gtk_notebook_set_current_page(GTK_NOTEBOOK(playlist_notebook), 0); } else { gtk_notebook_next_page(GTK_NOTEBOOK(playlist_notebook)); } } void playlist_tab_close(GtkButton * button, gpointer data) { playlist_t * pl = (playlist_t *)data; int n = gtk_notebook_get_n_pages(GTK_NOTEBOOK(playlist_notebook)); int i; if (pl->progbar_semaphore > 0 || pl->ms_semaphore > 0) { return; } for (i = 0; i < n; i++) { if (pl->widget == gtk_notebook_get_nth_page(GTK_NOTEBOOK(playlist_notebook), i)) { gtk_notebook_remove_page(GTK_NOTEBOOK(playlist_notebook), i); if (playlist_is_empty(pl)) { playlist_free(pl); } else { pl->closed = 1; pl->index = i; playlists_closed = g_list_prepend(playlists_closed, pl); playlists = g_list_remove(playlists, pl); } if (!options.playlist_always_show_tabs && gtk_notebook_get_n_pages(GTK_NOTEBOOK(playlist_notebook)) == 1) { gtk_notebook_set_show_tabs(GTK_NOTEBOOK(playlist_notebook), FALSE); } break; } } if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(playlist_notebook)) == 0) { playlist_tab_new(NULL); } } void playlist_tab_close_undo(void) { GList * first = g_list_first(playlists_closed); if (first != NULL) { playlist_t * pl = (playlist_t *)first->data; if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(playlist_notebook)) == 1) { playlist_t * pl = (playlist_t *)playlists->data; if (playlist_is_empty(pl)) { gtk_notebook_remove_page(GTK_NOTEBOOK(playlist_notebook), 0); playlist_free(pl); } } if (playlist_get_playing() != NULL) { pl->playing = 0; } pl->closed = 0; playlists_closed = g_list_delete_link(playlists_closed, first); playlists = g_list_insert(playlists, pl, pl->index); create_playlist_gui(pl); } } gint playlist_notebook_clicked(GtkWidget * widget, GdkEventButton * event, gpointer data) { if (event->type == GDK_2BUTTON_PRESS && event->button == 1 && event->y < 25 && event->x > 25 && event->x < widget->allocation.width - 25) { playlist_tab_new(NULL); return TRUE; } return FALSE; } gint playlist_tab_label_clicked(GtkWidget * widget, GdkEventButton * event, gpointer data) { playlist_t * pl = (playlist_t *)data; if (event->type == GDK_2BUTTON_PRESS && event->button == 1) { GtkTreePath * path = playlist_get_playing_path(pl); if (path != NULL) { playlist_start_playback_at_path(pl, path); gtk_tree_path_free(path); } else { GtkTreeIter iter; if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(pl->store), &iter)) { path = gtk_tree_model_get_path(GTK_TREE_MODEL(pl->store), &iter); playlist_start_playback_at_path(pl, path); gtk_tree_path_free(path); } } return TRUE; } if (event->button == 2) { playlist_tab_close(NULL, pl); return TRUE; } if (event->button == 3) { if (g_list_length(playlists_closed) > 0) { gtk_widget_set_sensitive(pl->tab__close_undo, TRUE); } else { gtk_widget_set_sensitive(pl->tab__close_undo, FALSE); } gtk_menu_popup(GTK_MENU(pl->tab_menu), NULL, NULL, NULL, NULL, event->button, event->time); return TRUE; } return FALSE; } gint tab__rename_key_press_cb (GtkWidget *widget, GdkEventKey *event, gpointer data) { if (event->keyval == GDK_Return) { gtk_dialog_response (GTK_DIALOG(widget), GTK_RESPONSE_ACCEPT); return TRUE; } return FALSE; } void tab__rename_cb(gpointer data) { GtkWidget * dialog; GtkWidget * table; GtkWidget * hbox; GtkWidget * hbox2; GtkWidget * entry; GtkWidget * label; char name[MAXLEN]; playlist_t * pl = (playlist_t *)data; dialog = gtk_dialog_new_with_buttons(_("Rename playlist"), options.playlist_is_embedded ? GTK_WINDOW(main_window) : GTK_WINDOW(playlist_window), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL); gtk_widget_set_size_request(GTK_WIDGET(dialog), 400, -1); gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER); gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_REJECT); g_signal_connect (G_OBJECT (dialog), "key_press_event", G_CALLBACK (tab__rename_key_press_cb), NULL); table = gtk_table_new(2, 2, FALSE); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), table, FALSE, TRUE, 2); label = gtk_label_new(_("Name:")); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(table), hbox, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 5, 5); hbox2 = gtk_hbox_new(FALSE, 0); gtk_table_attach(GTK_TABLE(table), hbox2, 1, 2, 0, 1, GTK_FILL | GTK_EXPAND, GTK_FILL, 0, 5); entry = gtk_entry_new(); gtk_entry_set_max_length(GTK_ENTRY(entry), MAXLEN - 1); gtk_entry_set_text(GTK_ENTRY(entry), pl->name); gtk_box_pack_start(GTK_BOX(hbox2), entry, TRUE, TRUE, 0); gtk_widget_grab_focus(entry); gtk_widget_show_all(dialog); display: name[0] = '\0'; if (aqualung_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { strncpy(name, gtk_entry_get_text(GTK_ENTRY(entry)), MAXLEN-1); if (name[0] == '\0') { gtk_widget_grab_focus(entry); goto display; } playlist_rename(pl, name); } gtk_widget_destroy(dialog); } void tab__new_cb(gpointer data) { playlist_tab_new(NULL); } void tab__close_cb(gpointer data) { playlist_t * pl = (playlist_t *)data; playlist_tab_close(NULL, pl); } void tab__close_undo_cb(gpointer data) { playlist_tab_close_undo(); } void tab__close_other_cb(gpointer data) { playlist_t * pl = (playlist_t *)data; GList * node; for (node = playlists; node && node->data != pl; node = playlists) { playlist_tab_close(NULL, node->data); } for (node = playlists->next; node && node->data != pl; node = playlists->next) { playlist_tab_close(NULL, node->data); } } void playlist_show_hide_close_buttons(gboolean state) { GList * list; for (list = playlists; list; list = list->next) { playlist_t * pl = (playlist_t *)list->data; if (state == TRUE) { gtk_widget_show(pl->tab_close_button); } else { gtk_widget_hide(pl->tab_close_button); } } } GtkWidget * create_playlist_tab_label(playlist_t * pl) { GtkWidget * hbox; GtkWidget * event_box; GtkWidget * image; GdkPixbuf * pixbuf; GtkWidget * separator; GtkWidget * tab__new; GtkWidget * tab__rename; GtkWidget * tab__close; GtkWidget * tab__close_other; char path[MAXLEN]; hbox = gtk_hbox_new(FALSE, 4); GTK_WIDGET_UNSET_FLAGS(hbox, GTK_CAN_FOCUS); event_box = gtk_event_box_new(); pl->label = gtk_label_new(pl->name); gtk_widget_set_name(pl->label, "playlist_tab_label"); gtk_container_add(GTK_CONTAINER(event_box), hbox); pl->tab_close_button = gtk_button_new(); gtk_widget_set_name(pl->tab_close_button, "playlist_tab_close_button"); sprintf(path, "%s/tab-close.png", AQUALUNG_DATADIR); if ((pixbuf = gdk_pixbuf_new_from_file(path, NULL)) != NULL) { image = gtk_image_new_from_pixbuf(pixbuf); gtk_container_add(GTK_CONTAINER(pl->tab_close_button), image); } gtk_button_set_relief(GTK_BUTTON(pl->tab_close_button), GTK_RELIEF_NONE); GTK_WIDGET_UNSET_FLAGS(pl->tab_close_button, GTK_CAN_FOCUS); gtk_widget_set_size_request(pl->tab_close_button, 16, 16); gtk_box_pack_start(GTK_BOX(hbox), pl->label, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(hbox), pl->tab_close_button, FALSE, FALSE, 0); gtk_widget_show_all(hbox); g_signal_connect(G_OBJECT(pl->tab_close_button), "clicked", G_CALLBACK(playlist_tab_close), pl); g_signal_connect(G_OBJECT(event_box), "button_press_event", G_CALLBACK(playlist_tab_label_clicked), pl); /* popup menu for tabs */ pl->tab_menu = gtk_menu_new(); tab__new = gtk_menu_item_new_with_label(_("New tab")); tab__rename = gtk_menu_item_new_with_label(_("Rename")); tab__close = gtk_menu_item_new_with_label(_("Close tab")); pl->tab__close_undo = gtk_menu_item_new_with_label(_("Undo close tab")); tab__close_other = gtk_menu_item_new_with_label(_("Close other tabs")); gtk_menu_shell_append(GTK_MENU_SHELL(pl->tab_menu), tab__new); gtk_menu_shell_append(GTK_MENU_SHELL(pl->tab_menu), tab__rename); separator = gtk_separator_menu_item_new(); gtk_menu_shell_append(GTK_MENU_SHELL(pl->tab_menu), separator); gtk_widget_show(separator); gtk_menu_shell_append(GTK_MENU_SHELL(pl->tab_menu), tab__close); gtk_menu_shell_append(GTK_MENU_SHELL(pl->tab_menu), pl->tab__close_undo); separator = gtk_separator_menu_item_new(); gtk_menu_shell_append(GTK_MENU_SHELL(pl->tab_menu), separator); gtk_widget_show(separator); gtk_menu_shell_append(GTK_MENU_SHELL(pl->tab_menu), tab__close_other); g_signal_connect_swapped(G_OBJECT(tab__new), "activate", G_CALLBACK(tab__new_cb), pl); g_signal_connect_swapped(G_OBJECT(tab__rename), "activate", G_CALLBACK(tab__rename_cb), pl); g_signal_connect_swapped(G_OBJECT(tab__close), "activate", G_CALLBACK(tab__close_cb), pl); g_signal_connect_swapped(G_OBJECT(pl->tab__close_undo), "activate", G_CALLBACK(tab__close_undo_cb), pl); g_signal_connect_swapped(G_OBJECT(tab__close_other), "activate", G_CALLBACK(tab__close_other_cb), pl); gtk_widget_show(tab__rename); gtk_widget_show(tab__new); gtk_widget_show(tab__close); gtk_widget_show(pl->tab__close_undo); gtk_widget_show(tab__close_other); if (options.playlist_show_close_button_in_tab == FALSE) { gtk_widget_hide(pl->tab_close_button); } return event_box; } void create_playlist_gui(playlist_t * pl) { GtkWidget * viewport; GtkCellRenderer * track_renderer; GtkCellRenderer * rva_renderer; GtkCellRenderer * length_renderer; int i; GdkPixbuf * pixbuf; gchar path[MAXLEN]; GtkTargetEntry source_table[] = { { "aqualung-list-list", GTK_TARGET_SAME_APP, 0 } }; GtkTargetEntry target_table[] = { { "aqualung-list-list", GTK_TARGET_SAME_APP, 0 }, { "aqualung-browser-list", GTK_TARGET_SAME_APP, 1 }, { "STRING", 0, 2 }, { "text/plain", 0, 2 }, { "text/uri-list", 0, 2 } }; pl->view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(pl->store)); gtk_tree_view_set_enable_search(GTK_TREE_VIEW(pl->view), FALSE); gtk_widget_set_name(pl->view, "play_list"); gtk_widget_set_size_request(pl->view, 100, 100); g_signal_connect(G_OBJECT(pl->view), "key_press_event", G_CALLBACK(playlist_key_pressed), NULL); if (options.override_skin_settings) { gtk_widget_modify_font(pl->view, fd_playlist); } if (options.enable_pl_rules_hint) { gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(pl->view), TRUE); } for (i = 0; i < 3; i++) { switch (options.plcol_idx[i]) { case 0: track_renderer = gtk_cell_renderer_text_new(); g_object_set((gpointer)track_renderer, "xalign", 0.0, NULL); pl->track_column = gtk_tree_view_column_new_with_attributes("Tracks", track_renderer, "text", PL_COL_NAME, "foreground", PL_COL_COLO, "weight", PL_COL_FONT, NULL); gtk_tree_view_column_set_sizing(GTK_TREE_VIEW_COLUMN(pl->track_column), GTK_TREE_VIEW_COLUMN_AUTOSIZE); gtk_tree_view_column_set_spacing(GTK_TREE_VIEW_COLUMN(pl->track_column), 3); gtk_tree_view_column_set_resizable(GTK_TREE_VIEW_COLUMN(pl->track_column), FALSE); g_object_set(G_OBJECT(track_renderer), "ellipsize", PANGO_ELLIPSIZE_END, NULL); gtk_tree_view_column_set_expand(GTK_TREE_VIEW_COLUMN(pl->track_column), TRUE); gtk_tree_view_append_column(GTK_TREE_VIEW(pl->view), pl->track_column); break; case 1: rva_renderer = gtk_cell_renderer_text_new(); g_object_set((gpointer)rva_renderer, "xalign", 1.0, NULL); pl->rva_column = gtk_tree_view_column_new_with_attributes("RVA", rva_renderer, "text", PL_COL_VADJ, "foreground", PL_COL_COLO, "weight", PL_COL_FONT, NULL); gtk_tree_view_column_set_sizing(GTK_TREE_VIEW_COLUMN(pl->rva_column), GTK_TREE_VIEW_COLUMN_AUTOSIZE); gtk_tree_view_column_set_spacing(GTK_TREE_VIEW_COLUMN(pl->rva_column), 3); if (options.show_rva_in_playlist) { gtk_tree_view_column_set_visible(GTK_TREE_VIEW_COLUMN(pl->rva_column), TRUE); } else { gtk_tree_view_column_set_visible(GTK_TREE_VIEW_COLUMN(pl->rva_column), FALSE); } gtk_tree_view_column_set_resizable(GTK_TREE_VIEW_COLUMN(pl->rva_column), FALSE); gtk_tree_view_append_column(GTK_TREE_VIEW(pl->view), pl->rva_column); break; case 2: length_renderer = gtk_cell_renderer_text_new(); g_object_set((gpointer)length_renderer, "xalign", 1.0, NULL); pl->length_column = gtk_tree_view_column_new_with_attributes("Length", length_renderer, "text", PL_COL_DURA, "foreground", PL_COL_COLO, "weight", PL_COL_FONT, NULL); gtk_tree_view_column_set_sizing(GTK_TREE_VIEW_COLUMN(pl->length_column), GTK_TREE_VIEW_COLUMN_AUTOSIZE); gtk_tree_view_column_set_spacing(GTK_TREE_VIEW_COLUMN(pl->length_column), 3); if (options.show_length_in_playlist) { gtk_tree_view_column_set_visible(GTK_TREE_VIEW_COLUMN(pl->length_column), TRUE); } else { gtk_tree_view_column_set_visible(GTK_TREE_VIEW_COLUMN(pl->length_column), FALSE); } gtk_tree_view_column_set_resizable(GTK_TREE_VIEW_COLUMN(pl->length_column), FALSE); gtk_tree_view_append_column(GTK_TREE_VIEW(pl->view), pl->length_column); } } gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(pl->view), FALSE); g_signal_connect(G_OBJECT(pl->view), "button_press_event", G_CALLBACK(doubleclick_handler), pl); /* setup drag and drop */ gtk_drag_source_set(pl->view, GDK_BUTTON1_MASK, source_table, sizeof(source_table) / sizeof(GtkTargetEntry), GDK_ACTION_MOVE); gtk_drag_dest_set(pl->view, GTK_DEST_DEFAULT_ALL, target_table, sizeof(target_table) / sizeof(GtkTargetEntry), GDK_ACTION_MOVE | GDK_ACTION_COPY); snprintf(path, MAXLEN-1, "%s/drag.png", AQUALUNG_DATADIR); if ((pixbuf = gdk_pixbuf_new_from_file(path, NULL)) != NULL) { gtk_drag_source_set_icon_pixbuf(pl->view, pixbuf); } g_signal_connect(G_OBJECT(pl->view), "drag_end", G_CALLBACK(playlist_drag_end), pl); g_signal_connect(G_OBJECT(pl->view), "drag_data_get", G_CALLBACK(playlist_drag_data_get), pl); g_signal_connect(G_OBJECT(pl->view), "drag_leave", G_CALLBACK(playlist_drag_leave), pl); g_signal_connect(G_OBJECT(pl->view), "drag_motion", G_CALLBACK(playlist_drag_motion), pl); g_signal_connect(G_OBJECT(pl->view), "drag_data_received", G_CALLBACK(playlist_drag_data_received), pl); pl->select = gtk_tree_view_get_selection(GTK_TREE_VIEW(pl->view)); gtk_tree_selection_set_mode(pl->select, GTK_SELECTION_MULTIPLE); g_signal_connect(G_OBJECT(pl->select), "changed", G_CALLBACK(playlist_selection_changed_cb), pl); pl->widget = gtk_vbox_new(FALSE, 2); viewport = gtk_viewport_new(NULL, NULL); gtk_box_pack_start(GTK_BOX(pl->widget), viewport, TRUE, TRUE, 0); pl->scroll = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(pl->scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); gtk_container_add(GTK_CONTAINER(viewport), pl->scroll); gtk_container_add(GTK_CONTAINER(pl->scroll), pl->view); pl->progbar_container = gtk_hbox_new(FALSE, 4); gtk_box_pack_start(GTK_BOX(pl->widget), pl->progbar_container, FALSE, FALSE, 0); if (pl->progbar_semaphore > 0) { pl->progbar_semaphore--; playlist_progress_bar_show(pl); } gtk_widget_show_all(pl->widget); gtk_notebook_insert_page(GTK_NOTEBOOK(playlist_notebook), pl->widget, create_playlist_tab_label(pl), pl->index); gtk_notebook_set_current_page(GTK_NOTEBOOK(playlist_notebook), pl->index); playlist_set_playing(pl, pl->playing); if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(playlist_notebook)) > 1) { gtk_notebook_set_show_tabs(GTK_NOTEBOOK(playlist_notebook), TRUE); } #if (GTK_CHECK_VERSION(2,10,0)) gtk_notebook_set_tab_reorderable(GTK_NOTEBOOK(playlist_notebook), pl->widget, TRUE); #endif /* GTK_CHECK_VERSION */ gtk_widget_grab_focus(pl->view); } playlist_t * playlist_tab_new(char * name) { playlist_t * pl = NULL; pl = playlist_new(name); create_playlist_gui(pl); return pl; } playlist_t * playlist_tab_new_if_nonempty(char * name) { playlist_t * pl = (playlist_t *)playlists->data; if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(playlist_notebook)) == 1 && playlist_is_empty(pl)) { playlist_rename(pl, name); return pl; } return playlist_tab_new(name); } void notebook_switch_page(GtkNotebook * notebook, GtkNotebookPage * page, guint page_num, gpointer user_data) { playlist_t * pl = playlist_get_by_page_num(page_num); if (pl == NULL) { return; } playlist_content_changed(pl); playlist_selection_changed(pl); } #if (GTK_CHECK_VERSION(2,10,0)) void notebook_page_reordered(GtkNotebook * notebook, GtkWidget * child, guint page_num, gpointer user_data) { GList * node; for (node = playlists; node; node = node->next) { playlist_t * pl = (playlist_t *)node->data; pl->index = gtk_notebook_page_num(notebook, pl->widget); } playlists = g_list_sort(playlists, playlist_compare_index); } #endif /* GTK_CHECK_VERSION */ void create_playlist(void) { GtkWidget * vbox; GtkWidget * statusbar; GtkWidget * statusbar_scrolledwin; GtkWidget * statusbar_viewport; GtkWidget * hbox_bottom; GtkWidget * add_button; GtkWidget * sel_button; GtkWidget * rem_button; if (pl_color_active[0] == '\0') { strcpy(pl_color_active, "#000080"); } if (pl_color_inactive[0] == '\0') { strcpy(pl_color_inactive, "#010101"); } /* window creating stuff */ if (!options.playlist_is_embedded) { playlist_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(playlist_window), _("Playlist")); gtk_container_set_border_width(GTK_CONTAINER(playlist_window), 2); g_signal_connect(G_OBJECT(playlist_window), "delete_event", G_CALLBACK(playlist_window_close), NULL); gtk_widget_set_size_request(playlist_window, 300, 200); } else { gtk_widget_set_size_request(playlist_window, 200, 200); } if (!options.playlist_is_embedded) { g_signal_connect(G_OBJECT(playlist_window), "key_press_event", G_CALLBACK(playlist_window_key_pressed), NULL); } gtk_widget_set_events(playlist_window, GDK_BUTTON_PRESS_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK); if (!options.playlist_is_embedded) { plist_menu = gtk_menu_new(); register_toplevel_window(plist_menu, TOP_WIN_SKIN); init_plist_menu(plist_menu); } vbox = gtk_vbox_new(FALSE, 2); gtk_container_add(GTK_CONTAINER(playlist_window), vbox); /* this widget should not be visually noticeable, it is only used for getting active and inactive playlist colors from the skin/rc file */ playlist_color_indicator = gtk_hbox_new(FALSE, 0); gtk_widget_set_name(playlist_color_indicator, "playlist_color_indicator"); gtk_box_pack_start(GTK_BOX(vbox), playlist_color_indicator, FALSE, FALSE, 0); /* create notebook */ playlist_notebook = gtk_notebook_new(); gtk_notebook_set_show_border(GTK_NOTEBOOK(playlist_notebook), FALSE); gtk_notebook_set_scrollable(GTK_NOTEBOOK(playlist_notebook), TRUE); gtk_notebook_set_show_tabs(GTK_NOTEBOOK(playlist_notebook), options.playlist_always_show_tabs); gtk_box_pack_start(GTK_BOX(vbox), playlist_notebook, TRUE, TRUE, 0); g_signal_connect(G_OBJECT(playlist_notebook), "key_press_event", G_CALLBACK(playlist_notebook_key_pressed), NULL); g_signal_connect(G_OBJECT(playlist_notebook), "button_press_event", G_CALLBACK(playlist_notebook_clicked), NULL); g_signal_connect(G_OBJECT(playlist_notebook), "switch_page", G_CALLBACK(notebook_switch_page), NULL); #if (GTK_CHECK_VERSION(2,10,0)) g_signal_connect(G_OBJECT(playlist_notebook), "page_reordered", G_CALLBACK(notebook_page_reordered), NULL); #endif /* GTK_CHECK_VERSION */ if (playlists != NULL) { GList * list; for (list = playlists; list; list = list->next) { playlist_t * pl = (playlist_t *)list->data; if (!pl->closed) { create_playlist_gui(pl); } } } /* statusbar */ if (options.enable_playlist_statusbar) { statusbar_scrolledwin = gtk_scrolled_window_new(NULL, NULL); GTK_WIDGET_UNSET_FLAGS(statusbar_scrolledwin, GTK_CAN_FOCUS); gtk_widget_set_size_request(statusbar_scrolledwin, 1, -1); /* MAGIC */ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(statusbar_scrolledwin), GTK_POLICY_NEVER, GTK_POLICY_NEVER); statusbar_viewport = gtk_viewport_new(NULL, NULL); gtk_widget_set_name(statusbar_viewport, "info_viewport"); gtk_container_add(GTK_CONTAINER(statusbar_scrolledwin), statusbar_viewport); gtk_box_pack_start(GTK_BOX(vbox), statusbar_scrolledwin, FALSE, TRUE, 2); gtk_widget_set_events(statusbar_viewport, GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK); g_signal_connect(G_OBJECT(statusbar_viewport), "button_press_event", G_CALLBACK(scroll_btn_pressed), NULL); g_signal_connect(G_OBJECT(statusbar_viewport), "button_release_event", G_CALLBACK(scroll_btn_released), (gpointer)statusbar_scrolledwin); g_signal_connect(G_OBJECT(statusbar_viewport), "motion_notify_event", G_CALLBACK(scroll_motion_notify), (gpointer)statusbar_scrolledwin); statusbar = gtk_hbox_new(FALSE, 0); gtk_container_set_border_width(GTK_CONTAINER(statusbar), 1); gtk_container_add(GTK_CONTAINER(statusbar_viewport), statusbar); statusbar_selected = gtk_label_new(""); gtk_widget_set_name(statusbar_selected, "label_info"); gtk_box_pack_end(GTK_BOX(statusbar), statusbar_selected, FALSE, TRUE, 0); statusbar_selected_label = gtk_label_new(_(" Selected: ")); gtk_widget_set_name(statusbar_selected_label, "label_info"); gtk_box_pack_end(GTK_BOX(statusbar), statusbar_selected_label, FALSE, TRUE, 0); gtk_box_pack_end(GTK_BOX(statusbar), gtk_vseparator_new(), FALSE, TRUE, 5); statusbar_total = gtk_label_new(""); gtk_widget_set_name(statusbar_total, "label_info"); gtk_box_pack_end(GTK_BOX(statusbar), statusbar_total, FALSE, TRUE, 0); statusbar_total_label = gtk_label_new(_("Total: ")); gtk_widget_set_name(statusbar_total_label, "label_info"); gtk_box_pack_end(GTK_BOX(statusbar), statusbar_total_label, FALSE, TRUE, 0); } playlist_set_font(options.override_skin_settings); /* bottom area of playlist window */ hbox_bottom = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox), hbox_bottom, FALSE, TRUE, 0); add_button = gtk_button_new_with_label(_("Add files")); GTK_WIDGET_UNSET_FLAGS(add_button, GTK_CAN_FOCUS); aqualung_widget_set_tooltip_text(add_button, _("Add files to playlist\n(Press right mouse button for menu)")); gtk_box_pack_start(GTK_BOX(hbox_bottom), add_button, TRUE, TRUE, 0); g_signal_connect(G_OBJECT(add_button), "clicked", G_CALLBACK(add_files), NULL); sel_button = gtk_button_new_with_label(_("Select all")); GTK_WIDGET_UNSET_FLAGS(sel_button, GTK_CAN_FOCUS); aqualung_widget_set_tooltip_text(sel_button, _("Select all songs in playlist\n(Press right mouse button for menu)")); gtk_box_pack_start(GTK_BOX(hbox_bottom), sel_button, TRUE, TRUE, 0); g_signal_connect(G_OBJECT(sel_button), "clicked", G_CALLBACK(select_all), NULL); rem_button = gtk_button_new_with_label(_("Remove selected")); GTK_WIDGET_UNSET_FLAGS(rem_button, GTK_CAN_FOCUS); aqualung_widget_set_tooltip_text(rem_button, _("Remove selected songs from playlist\n(Press right mouse button for menu)")); gtk_box_pack_start(GTK_BOX(hbox_bottom), rem_button, TRUE, TRUE, 0); g_signal_connect(G_OBJECT(rem_button), "clicked", G_CALLBACK(remove_sel), NULL); add_menu = gtk_menu_new(); register_toplevel_window(add_menu, TOP_WIN_SKIN); add__dir = gtk_menu_item_new_with_label(_("Add directory")); gtk_menu_shell_append(GTK_MENU_SHELL(add_menu), add__dir); g_signal_connect_swapped(G_OBJECT(add__dir), "activate", G_CALLBACK(add__dir_cb), NULL); gtk_widget_show(add__dir); add__url = gtk_menu_item_new_with_label(_("Add URL")); gtk_menu_shell_append(GTK_MENU_SHELL(add_menu), add__url); g_signal_connect_swapped(G_OBJECT(add__url), "activate", G_CALLBACK(add__url_cb), NULL); gtk_widget_show(add__url); add__files = gtk_menu_item_new_with_label(_("Add files")); gtk_menu_shell_append(GTK_MENU_SHELL(add_menu), add__files); g_signal_connect_swapped(G_OBJECT(add__files), "activate", G_CALLBACK(add__files_cb), NULL); gtk_widget_show(add__files); g_signal_connect_swapped(G_OBJECT(add_button), "event", G_CALLBACK(add_cb), NULL); sel_menu = gtk_menu_new(); register_toplevel_window(sel_menu, TOP_WIN_SKIN); sel__none = gtk_menu_item_new_with_label(_("Select none")); gtk_menu_shell_append(GTK_MENU_SHELL(sel_menu), sel__none); g_signal_connect_swapped(G_OBJECT(sel__none), "activate", G_CALLBACK(sel__none_cb), NULL); gtk_widget_show(sel__none); sel__inv = gtk_menu_item_new_with_label(_("Invert selection")); gtk_menu_shell_append(GTK_MENU_SHELL(sel_menu), sel__inv); g_signal_connect_swapped(G_OBJECT(sel__inv), "activate", G_CALLBACK(sel__inv_cb), NULL); gtk_widget_show(sel__inv); sel__all = gtk_menu_item_new_with_label(_("Select all")); gtk_menu_shell_append(GTK_MENU_SHELL(sel_menu), sel__all); g_signal_connect_swapped(G_OBJECT(sel__all), "activate", G_CALLBACK(sel__all_cb), NULL); gtk_widget_show(sel__all); g_signal_connect_swapped(G_OBJECT(sel_button), "event", G_CALLBACK(sel_cb), NULL); rem_menu = gtk_menu_new(); register_toplevel_window(rem_menu, TOP_WIN_SKIN); rem__all = gtk_menu_item_new_with_label(_("Remove all")); gtk_menu_shell_append(GTK_MENU_SHELL(rem_menu), rem__all); g_signal_connect_swapped(G_OBJECT(rem__all), "activate", G_CALLBACK(rem__all_cb), NULL); gtk_widget_show(rem__all); rem__dead = gtk_menu_item_new_with_label(_("Remove dead")); gtk_menu_shell_append(GTK_MENU_SHELL(rem_menu), rem__dead); g_signal_connect_swapped(G_OBJECT(rem__dead), "activate", G_CALLBACK(rem__dead_cb), NULL); gtk_widget_show(rem__dead); cut__sel = gtk_menu_item_new_with_label(_("Cut selected")); gtk_menu_shell_append(GTK_MENU_SHELL(rem_menu), cut__sel); g_signal_connect_swapped(G_OBJECT(cut__sel), "activate", G_CALLBACK(cut__sel_cb), NULL); gtk_widget_show(cut__sel); rem__sel = gtk_menu_item_new_with_label(_("Remove selected")); gtk_menu_shell_append(GTK_MENU_SHELL(rem_menu), rem__sel); g_signal_connect_swapped(G_OBJECT(rem__sel), "activate", G_CALLBACK(rem__sel_cb), NULL); gtk_widget_show(rem__sel); g_signal_connect_swapped(G_OBJECT(rem_button), "event", G_CALLBACK(rem_cb), NULL); } void playlist_ensure_tab_exists() { if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(playlist_notebook)) == 0) { playlist_tab_new(NULL); } } void show_playlist(void) { options.playlist_on = 1; if (!options.playlist_is_embedded) { gtk_window_move(GTK_WINDOW(playlist_window), options.playlist_pos_x, options.playlist_pos_y); gtk_window_resize(GTK_WINDOW(playlist_window), options.playlist_size_x, options.playlist_size_y); register_toplevel_window(playlist_window, TOP_WIN_SKIN | TOP_WIN_TRAY); } else { gtk_window_get_size(GTK_WINDOW(main_window), &options.main_size_x, &options.main_size_y); gtk_window_resize(GTK_WINDOW(main_window), options.main_size_x, options.main_size_y + options.playlist_size_y + 6); } gtk_widget_show_all(playlist_window); } void hide_playlist(void) { options.playlist_on = 0; if (!options.playlist_is_embedded) { gtk_window_get_position(GTK_WINDOW(playlist_window), &options.playlist_pos_x, &options.playlist_pos_y); gtk_window_get_size(GTK_WINDOW(playlist_window), &options.playlist_size_x, &options.playlist_size_y); register_toplevel_window(playlist_window, TOP_WIN_SKIN); } else { options.playlist_size_x = playlist_window->allocation.width; options.playlist_size_y = playlist_window->allocation.height; gtk_window_get_size(GTK_WINDOW(main_window), &options.main_size_x, &options.main_size_y); } gtk_widget_hide(playlist_window); if (options.playlist_is_embedded) { gtk_window_resize(GTK_WINDOW(main_window), options.main_size_x, options.main_size_y - options.playlist_size_y - 6); } } xmlNodePtr save_track_node(playlist_t * pl, GtkTreeIter * piter, xmlNodePtr root, char * nodeID) { gchar str[32]; xmlNodePtr node; playlist_data_t * data; gtk_tree_model_get(GTK_TREE_MODEL(pl->store), piter, PL_COL_DATA, &data, -1); node = xmlNewTextChild(root, NULL, (const xmlChar*) nodeID, NULL); xmlNewTextChild(node, NULL, (const xmlChar*) "artist", (const xmlChar*) data->artist); xmlNewTextChild(node, NULL, (const xmlChar*) "album", (const xmlChar*) data->album); if (strcmp(nodeID, "record")) { char * file = NULL; xmlNewTextChild(node, NULL, (const xmlChar*) "title", (const xmlChar*) data->title); xmlNewTextChild(node, NULL, (const xmlChar*) "display", (const xmlChar*) data->display); if (cdda_is_cdtrack(data->file) || httpc_is_url(data->file)) { file = g_strdup(data->file); } else { file = g_filename_to_uri(data->file, NULL, NULL); } xmlNewTextChild(node, NULL, (const xmlChar*) "file", (const xmlChar*) file); g_free(file); snprintf(str, 31, "%f", data->voladj); xmlNewTextChild(node, NULL, (const xmlChar*) "voladj", (const xmlChar*) str); snprintf(str, 31, "%u", data->size); xmlNewTextChild(node, NULL, (const xmlChar*) "size", (const xmlChar*) str); } else if (IS_PL_ACTIVE(data)){ snprintf(str, 31, "%u", data->ntracks); xmlNewTextChild(node, NULL, (const xmlChar*) "ntracks", (const xmlChar*) str); snprintf(str, 31, "%u", data->actrack); xmlNewTextChild(node, NULL, (const xmlChar*) "actrack", (const xmlChar*) str); } snprintf(str, 31, "%f", data->duration); xmlNewTextChild(node, NULL, (const xmlChar*) "duration", (const xmlChar*) str); if (IS_PL_ACTIVE(data)) { xmlNewTextChild(node, NULL, (const xmlChar*) "active", NULL); } if (IS_PL_COVER(data)) { xmlNewTextChild(node, NULL, (const xmlChar*) "cover", NULL); } return node; } void playlist_save_data(playlist_t * pl, xmlNodePtr dest, int current) { gint i = 0; GtkTreeIter iter; GtkTreePath * p = NULL; if (pl->name_set) { xmlNewTextChild(dest, NULL, (const xmlChar*) "name", (const xmlChar*) pl->name); } if (pl->playing) { xmlNewTextChild(dest, NULL, (const xmlChar*) "active", NULL); } if (current) { xmlNewTextChild(dest, NULL, (const xmlChar*) "current", NULL); } if ((p = playlist_get_playing_path(pl)) != NULL) { xmlNewTextChild(dest, NULL, (const xmlChar*) "has_active_track", NULL); gtk_tree_path_free(p); } while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(pl->store), &iter, NULL, i++)) { gint n = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(pl->store), &iter); if (n) { /* album node */ gint j = 0; GtkTreeIter iter_child; xmlNodePtr node; node = save_track_node(pl, &iter, dest, "record"); while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(pl->store), &iter_child, &iter, j++)) { save_track_node(pl, &iter_child, node, "track"); } } else { /* track node */ save_track_node(pl, &iter, dest, "track"); } } } void playlist_save(playlist_t * pl, char * filename) { xmlDocPtr doc; xmlNodePtr root; doc = xmlNewDoc((const xmlChar*) "1.0"); root = xmlNewNode(NULL, (const xmlChar*) "aqualung_playlist"); xmlDocSetRootElement(doc, root); playlist_save_data(pl, root, 0); xmlSaveFormatFile(filename, doc, 1); xmlFreeDoc(doc); } int playlist_save_m3u_node(playlist_t * pl, GtkTreeIter * iter, FILE * f) { playlist_data_t * data; size_t fn_len; gtk_tree_model_get(GTK_TREE_MODEL(pl->store), iter, PL_COL_DATA, &data, -1); fn_len = strlen(data->file); if (fwrite(data->file, 1, fn_len, f) != fn_len) { g_warning("Error writing the playlist file"); return -1; } if (fwrite("\n", 1, 1, f) != 1) { g_warning("Error writing the playlist file"); return -1; } return 0; } void playlist_save_m3u(playlist_t * pl, char * filename) { FILE * f; gint i = 0; GtkTreeIter iter; if ((f = g_fopen(filename, "wb")) == NULL) { g_warning("Unable to open playlist file %s for writing", filename); return; } while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(pl->store), &iter, NULL, i++)) { gint n = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(pl->store), &iter); if (n) { /* album node */ gint j = 0; GtkTreeIter iter_child; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(pl->store), &iter_child, &iter, j++)) { if (playlist_save_m3u_node(pl, &iter_child, f) != 0) { goto playlist_save_m3u_cleanup; } } } else { /* track node */ if (playlist_save_m3u_node(pl, &iter, f) != 0) { goto playlist_save_m3u_cleanup; } } } playlist_save_m3u_cleanup: if (fclose(f) != 0) { g_warning("Unable to close playlist file %s", filename); } } void playlist_save_all(char * filename) { xmlDocPtr doc; xmlNodePtr root; xmlNodePtr tab; GList * list = NULL; int current = gtk_notebook_get_current_page(GTK_NOTEBOOK(playlist_notebook)); int i = 0; doc = xmlNewDoc((const xmlChar*) "1.0"); root = xmlNewNode(NULL, (const xmlChar*) "aqualung_playlist_tabs"); xmlDocSetRootElement(doc, root); for (list = playlists; list; list = list->next) { playlist_t * pl = (playlist_t *)list->data; tab = xmlNewTextChild(root, NULL, (const xmlChar*) "tab", NULL); playlist_save_data(pl, tab, (i == current)); i++; } xmlSaveFormatFile(filename, doc, 1); xmlFreeDoc(doc); } gboolean playlist_auto_save_cb(gpointer data) { if (playlist_dirty) { char playlist_name[MAXLEN]; snprintf(playlist_name, MAXLEN-1, "%s/%s", options.confdir, "playlist.xml"); playlist_save_all(playlist_name); playlist_dirty = 0; } return TRUE; } void playlist_auto_save_reset(void) { if (playlist_auto_save_tag != -1) { g_source_remove(playlist_auto_save_tag); } if (options.playlist_auto_save) { playlist_auto_save_tag = aqualung_timeout_add(options.playlist_auto_save_int * 60000, playlist_auto_save_cb, NULL); } } xmlChar * parse_playlist_name(xmlDocPtr doc, xmlNodePtr _cur) { xmlNodePtr cur; for (cur = _cur->xmlChildrenNode; cur != NULL; cur = cur->next) { if (!xmlStrcmp(cur->name, (const xmlChar *)"name")) { return xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); } } return NULL; } void parse_playlist_status(xmlDocPtr doc, xmlNodePtr _cur, int * active, int * current, int * has_active) { xmlNodePtr cur; if (active) { *active = 0; } if (current) { *current = 0; } if (has_active) { *has_active = 0; } for (cur = _cur->xmlChildrenNode; cur != NULL; cur = cur->next) { if (active && !xmlStrcmp(cur->name, (const xmlChar *)"active")) { *active = 1; } if (current && !xmlStrcmp(cur->name, (const xmlChar *)"current")) { *current = 1; } if (has_active && !xmlStrcmp(cur->name, (const xmlChar *)"has_active_track")) { *has_active = 1; } } } void parse_playlist_track(playlist_transfer_t * pt, xmlDocPtr doc, xmlNodePtr _cur, int flags) { xmlChar * key; xmlNodePtr cur; playlist_data_t * data = NULL; if ((data = playlist_data_new()) == NULL) { return; } data->flags = flags; for (cur = _cur->xmlChildrenNode; cur != NULL; cur = cur->next) { if (!xmlStrcmp(cur->name, (const xmlChar *)"artist")) { if ((key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1)) != NULL) { data->artist = strndup((char *)key, MAXLEN-1); xmlFree(key); } } else if (!xmlStrcmp(cur->name, (const xmlChar *)"album")) { if ((key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1)) != NULL) { data->album = strndup((char *)key, MAXLEN-1); xmlFree(key); } } else if (!xmlStrcmp(cur->name, (const xmlChar *)"title")) { if ((key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1)) != NULL) { data->title = strndup((char *)key, MAXLEN-1); xmlFree(key); } } else if (!xmlStrcmp(cur->name, (const xmlChar *)"display")) { if ((key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1)) != NULL) { data->display = strndup((char *)key, MAXLEN-1); xmlFree(key); } } else if (!xmlStrcmp(cur->name, (const xmlChar *)"file")) { if ((key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1)) != NULL) { gchar * tmp; if ((tmp = g_filename_from_uri((char *) key, NULL, NULL))) { data->file = strndup(tmp, MAXLEN-1); g_free(tmp); } else { data->file = strndup((char *)key, MAXLEN-1); } xmlFree(key); } } else if (!xmlStrcmp(cur->name, (const xmlChar *)"voladj")) { if ((key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1)) != NULL) { data->voladj = convf((char *)key); xmlFree(key); } } else if (!xmlStrcmp(cur->name, (const xmlChar *)"duration")) { if ((key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1)) != NULL) { data->duration = convf((char *)key); xmlFree(key); } } else if (!xmlStrcmp(cur->name, (const xmlChar *)"size")) { if ((key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1)) != NULL) { sscanf((char *)key, "%u", &data->size); xmlFree(key); } } else if (!xmlStrcmp(cur->name, (const xmlChar *)"ntracks")) { if ((key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1)) != NULL) { sscanf((char *)key, "%hu", &data->ntracks); xmlFree(key); } } else if (!xmlStrcmp(cur->name, (const xmlChar *)"actrack")) { if ((key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1)) != NULL) { sscanf((char *)key, "%hu", &data->actrack); xmlFree(key); } } else if (!xmlStrcmp(cur->name, (const xmlChar *)"active")) { PL_SET_FLAG(data, PL_FLAG_ACTIVE); } else if (!xmlStrcmp(cur->name, (const xmlChar *)"cover")) { PL_SET_FLAG(data, PL_FLAG_COVER); } } if (IS_PL_ALBUM_NODE(data)) { int act_flag = 0; if (flags & PL_FLAG_ACTIVE) { /* ACTIVE flag has been forced by playlist_load_xml_thread */ act_flag = PL_FLAG_ACTIVE; data->actrack = 1; for (cur = _cur->xmlChildrenNode; cur != NULL; cur = cur->next) { if (!xmlStrcmp(cur->name, (const xmlChar *)"track")) { data->ntracks++; } } } playlist_thread_add_to_list(pt, data); for (cur = _cur->xmlChildrenNode; cur != NULL; cur = cur->next) { if (!xmlStrcmp(cur->name, (const xmlChar *)"track")) { parse_playlist_track(pt, doc, cur, PL_FLAG_ALBUM_CHILD | act_flag); act_flag = 0; } } } else if (data->file != NULL) { playlist_thread_add_to_list(pt, data); } } void * playlist_load_xml_thread(void * arg) { playlist_transfer_t * pt = (playlist_transfer_t *)arg; xmlDocPtr doc = (xmlDocPtr)pt->xml_doc; xmlNodePtr cur = (xmlNodePtr)pt->xml_node; int act_flag = 0; AQUALUNG_THREAD_DETACH(); AQUALUNG_MUTEX_LOCK(pt->pl->thread_mutex); if (pt->start_playback) { int has_active; parse_playlist_status(doc, cur, NULL, NULL, &has_active); if (!has_active) { act_flag = PL_FLAG_ACTIVE; } } for (cur = cur->xmlChildrenNode; cur != NULL && !pt->pl->thread_stop; cur = cur->next) { if (!xmlStrcmp(cur->name, (const xmlChar *)"track")) { parse_playlist_track(pt, doc, cur, act_flag); act_flag = 0; } if (!xmlStrcmp(cur->name, (const xmlChar *)"record")) { parse_playlist_track(pt, doc, cur, PL_FLAG_ALBUM_NODE | act_flag); act_flag = 0; } } playlist_thread_add_to_list(pt, NULL); AQUALUNG_MUTEX_UNLOCK(pt->pl->thread_mutex); playlist_transfer_free(pt); return NULL; } void playlist_load_xml_single(char * filename, playlist_transfer_t * pt) { xmlDocPtr doc; xmlNodePtr cur; doc = xmlParseFile(filename); if (doc == NULL) { fprintf(stderr, "An XML error occured while parsing %s\n", filename); return; } cur = xmlDocGetRootElement(doc); if (cur == NULL) { fprintf(stderr, "empty XML document\n"); xmlFreeDoc(doc); return; } if (xmlStrcmp(cur->name, (const xmlChar *)"aqualung_playlist")) { fprintf(stderr, "XML document of the wrong type\n"); xmlFreeDoc(doc); return; } if (!pt->pl->name_set || pt->clear) { xmlChar * pl_name = parse_playlist_name(doc, cur); if (pl_name != NULL) { playlist_rename(pt->pl, (char *)pl_name); xmlFree(pl_name); } } if (playlist_get_playing() == NULL) { int pl_act; parse_playlist_status(doc, cur, &pl_act, NULL, NULL); playlist_set_playing(pt->pl, pl_act); } pt->xml_doc = doc; pt->xml_node = cur; playlist_progress_bar_show(pt->pl); AQUALUNG_THREAD_CREATE(pt->pl->thread_id, NULL, playlist_load_xml_thread, pt); } void playlist_load_xml_multi(char * filename, int start_playback) { xmlDocPtr doc; xmlNodePtr root; xmlNodePtr cur; int * ref = NULL; int current = -1; int force_active = start_playback; int i = gtk_notebook_get_n_pages(GTK_NOTEBOOK(playlist_notebook)); doc = xmlParseFile(filename); if (doc == NULL) { fprintf(stderr, "An XML error occured while parsing %s\n", filename); return; } root = xmlDocGetRootElement(doc); if (root == NULL) { fprintf(stderr, "empty XML document\n"); xmlFreeDoc(doc); return; } if (xmlStrcmp(root->name, (const xmlChar *)"aqualung_playlist_tabs")) { fprintf(stderr, "XML document of the wrong type\n"); xmlFreeDoc(doc); return; } if ((ref = (int *)malloc(sizeof(int *))) == NULL) { fprintf(stderr, "playlist_load_xml_multi(): malloc error\n"); return; } *ref = 1; if (start_playback) { for (cur = root->xmlChildrenNode; cur != NULL; cur = cur->next) { if (!xmlStrcmp(cur->name, (const xmlChar *)"tab")) { int pl_act; parse_playlist_status(doc, cur, &pl_act, NULL, NULL); if (pl_act) { force_active = 0; break; } } } } for (cur = root->xmlChildrenNode; cur != NULL; cur = cur->next) { if (!xmlStrcmp(cur->name, (const xmlChar *)"tab")) { playlist_t * pl = NULL; playlist_transfer_t * pt = NULL; xmlChar * pl_name = NULL; int pl_act, pl_cur; pl_name = parse_playlist_name(doc, cur); pl = playlist_tab_new((char *)pl_name); if (pl_name != NULL) { xmlFree(pl_name); } parse_playlist_status(doc, cur, &pl_act, &pl_cur, NULL); if (playlist_get_playing() == NULL) { playlist_set_playing(pl, pl_act); } pt = playlist_transfer_new(pl); pt->xml_doc = doc; pt->xml_node = cur; pt->xml_ref = ref; *ref += 1; if (pl_act || (pl_cur && force_active)) { pt->start_playback = start_playback; start_playback = 0; force_active = 0; } if (pl_cur) { current = i; } ++i; playlist_progress_bar_show(pt->pl); AQUALUNG_THREAD_CREATE(pt->pl->thread_id, NULL, playlist_load_xml_thread, pt); } } *ref -= 1; gtk_notebook_set_current_page(GTK_NOTEBOOK(playlist_notebook), current); } void * playlist_load_m3u_thread(void * arg) { FILE * f; gint c; gint i = 0; gint n; gchar * str; gchar line[MAXLEN]; gchar name[MAXLEN]; gchar path[MAXLEN]; gchar tmp[MAXLEN]; gchar pl_dir[MAXLEN]; gint have_name = 0; playlist_transfer_t * pt = (playlist_transfer_t *)arg; playlist_data_t * data = NULL; AQUALUNG_THREAD_DETACH(); AQUALUNG_MUTEX_LOCK(pt->pl->thread_mutex); if ((f = fopen(pt->filename, "rb")) == NULL) { fprintf(stderr, "unable to open .m3u playlist: %s\n", pt->filename); goto finish; } str = strrchr(pt->filename, '/'); for (i = 0; (i < (str - pt->filename)) && (i < MAXLEN-1); i++) { pl_dir[i] = pt->filename[i]; } pl_dir[i] = '\0'; i = 0; while ((c = fgetc(f)) != EOF && !pt->pl->thread_stop) { if ((c != '\n') && (c != '\r') && (i < MAXLEN)) { if ((i > 0) || ((c != ' ') && (c != '\t'))) { line[i++] = c; } } else { line[i] = '\0'; if (i == 0) { continue; } i = 0; if (strstr(line, "#EXTM3U") == line) { continue; } if (strstr(line, "#EXTINF:") == line) { char str_duration[64]; int cnt = 0; /* We parse the timing, but throw it away. This may change in the future. */ while ((line[cnt+8] >= '0') && (line[cnt+8] <= '9') && cnt < 63) { str_duration[cnt] = line[cnt+8]; ++cnt; } str_duration[cnt] = '\0'; snprintf(name, MAXLEN-1, "%s", line+cnt+9); have_name = 1; } else { if (!httpc_is_url(line)) { /* safeguard against C:\ stuff */ if ((line[1] == ':') && (line[2] == '\\')) { fprintf(stderr, "Ignoring playlist item: %s\n", line); i = 0; have_name = 0; continue; } snprintf(path, MAXLEN-1, "%s", line); /* path curing: turn \-s into /-s */ for (n = 0; n < strlen(path); n++) { if (path[n] == '\\') path[n] = '/'; } if (path[0] != '/') { strncpy(tmp, path, MAXLEN-1); snprintf(path, MAXLEN-1, "%s/%s", pl_dir, tmp); } if (!have_name) { gchar * ch; if ((ch = strrchr(path, '/')) != NULL) { ++ch; snprintf(name, MAXLEN-1, "%s", ch); } else { fprintf(stderr, "warning: ain't this a directory? : %s\n", path); snprintf(name, MAXLEN-1, "%s", path); } } data = playlist_filemeta_get(path); } else { data = playlist_filemeta_get(line); } if (have_name && data != NULL) { free_strdup(&data->title, name); } have_name = 0; if (data == NULL) { fprintf(stderr, "load_m3u(): playlist_filemeta_get() returned NULL\n"); } else { playlist_thread_add_to_list(pt, data); } } } } playlist_thread_add_to_list(pt, NULL); finish: AQUALUNG_MUTEX_UNLOCK(pt->pl->thread_mutex); playlist_transfer_free(pt); return NULL; } void load_pls_load(playlist_transfer_t * pt, char * file, char * title, gint * have_file, gint * have_title) { playlist_data_t * data = NULL; if (*have_file == 0) { return; } data = playlist_filemeta_get(file); if (data && *have_title) { free_strdup(&data->title, title); } if (data == NULL) { fprintf(stderr, "load_pls_load(): playlist_filemeta_get() returned NULL\n"); } else { playlist_thread_add_to_list(pt, data); } *have_file = *have_title = 0; } void * playlist_load_pls_thread(void * arg) { FILE * f; gint c; gint i = 0; gint n; gchar * str; gchar line[MAXLEN]; gchar file[MAXLEN]; gchar title[MAXLEN]; gchar tmp[MAXLEN]; gchar pl_dir[MAXLEN]; gint have_file = 0; gint have_title = 0; gchar numstr_file[10]; gchar numstr_title[10]; playlist_transfer_t * pt = (playlist_transfer_t *)arg; AQUALUNG_THREAD_DETACH(); AQUALUNG_MUTEX_LOCK(pt->pl->thread_mutex); if ((f = fopen(pt->filename, "rb")) == NULL) { fprintf(stderr, "unable to open .pls playlist: %s\n", pt->filename); goto finish; } str = strrchr(pt->filename, '/'); for (i = 0; (i < (str - pt->filename)) && (i < MAXLEN-1); i++) { pl_dir[i] = pt->filename[i]; } pl_dir[i] = '\0'; i = 0; while ((c = fgetc(f)) != EOF && !pt->pl->thread_stop) { if ((c != '\n') && (c != '\r') && (i < MAXLEN)) { if ((i > 0) || ((c != ' ') && (c != '\t'))) { line[i++] = c; } } else { line[i] = '\0'; if (i == 0) continue; i = 0; if (strstr(line, "[playlist]") == line) { continue; } if (strcasestr(line, "NumberOfEntries") == line) { continue; } if (strstr(line, "Version") == line) { continue; } if (strstr(line, "File") == line) { char numstr[10]; char * ch; int m; if (have_file) { load_pls_load(pt, file, title, &have_file, &have_title); } if ((ch = strstr(line, "=")) == NULL) { fprintf(stderr, "Syntax error in %s\n", pt->filename); goto finish; } ++ch; while ((*ch == ' ') || (*ch == '\t')) ++ch; if (!httpc_is_url(ch)) { m = 0; for (n = 0; (line[n+4] != '=') && (m < sizeof(numstr)); n++) { if ((line[n+4] != ' ') && (line[n+4] != '\t')) numstr[m++] = line[n+4]; } numstr[m] = '\0'; strncpy(numstr_file, numstr, sizeof(numstr_file)); /* safeguard against C:\ stuff */ if ((ch[1] == ':') && (ch[2] == '\\')) { fprintf(stderr, "Ignoring playlist item: %s\n", ch); i = 0; have_file = have_title = 0; continue; } snprintf(file, MAXLEN-1, "%s", ch); /* path curing: turn \-s into /-s */ for (n = 0; n < strlen(file); n++) { if (file[n] == '\\') file[n] = '/'; } if (file[0] != '/') { strncpy(tmp, file, MAXLEN-1); snprintf(file, MAXLEN-1, "%s/%s", pl_dir, tmp); } } else { snprintf(file, MAXLEN-1, "%s", ch); } have_file = 1; } else if (strstr(line, "Title") == line) { char numstr[10]; char * ch; int m; if ((ch = strstr(line, "=")) == NULL) { fprintf(stderr, "Syntax error in %s\n", pt->filename); goto finish; } ++ch; while ((*ch == ' ') || (*ch == '\t')) ++ch; m = 0; for (n = 0; (line[n+5] != '=') && (m < sizeof(numstr)); n++) { if ((line[n+5] != ' ') && (line[n+5] != '\t')) numstr[m++] = line[n+5]; } numstr[m] = '\0'; strncpy(numstr_title, numstr, sizeof(numstr_title)); snprintf(title, MAXLEN-1, "%s", ch); have_title = 1; } else if (strstr(line, "Length") == line) { /* We parse the timing, but throw it away. This may change in the future. */ char * ch; if ((ch = strstr(line, "=")) == NULL) { fprintf(stderr, "Syntax error in %s\n", pt->filename); goto finish; } ++ch; while ((*ch == ' ') || (*ch == '\t')) ++ch; } else { fprintf(stderr, "Syntax error: invalid line in playlist: %s\n", line); goto finish; } if (!have_file || !have_title) { continue; } if (strcmp(numstr_file, numstr_title) != 0) { continue; } load_pls_load(pt, file, title, &have_file, &have_title); } } load_pls_load(pt, file, title, &have_file, &have_title); playlist_thread_add_to_list(pt, NULL); finish: AQUALUNG_MUTEX_UNLOCK(pt->pl->thread_mutex); playlist_transfer_free(pt); return NULL; } int playlist_get_type(char * filename) { FILE * f; gchar buf1[] = "\n\nstore), &iter)) { do { gtk_tree_model_get(GTK_TREE_MODEL(pl->store), &iter, PL_COL_DATA, &data, -1); if (IS_PL_ACTIVE(data)) { flag = 1; break; } } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(pl->store), &iter)); if (!flag) { gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(pl->store), &iter, NULL, 0); } set_cursor_in_playlist(pl, &iter, TRUE); } } void show_active_position_in_playlist_toggle(playlist_t * pl) { GtkTreeIter iter, iter_child; playlist_data_t * data; int flag, cflag, j; flag = cflag = 0; if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(pl->store), &iter)) { do { gtk_tree_model_get(GTK_TREE_MODEL(pl->store), &iter, PL_COL_DATA, &data, -1); if (IS_PL_ACTIVE(data)) { flag = 1; if (gtk_tree_selection_iter_is_selected(pl->select, &iter) && gtk_tree_model_iter_n_children(GTK_TREE_MODEL(pl->store), &iter)) { GtkTreePath * visible_path; gtk_tree_view_get_cursor(GTK_TREE_VIEW(pl->view), &visible_path, NULL); if (!gtk_tree_view_row_expanded(GTK_TREE_VIEW(pl->view), visible_path)) { gtk_tree_view_expand_row(GTK_TREE_VIEW(pl->view), visible_path, FALSE); } gtk_tree_path_free(visible_path); j = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(pl->store), &iter_child, &iter, j++)) { gtk_tree_model_get(GTK_TREE_MODEL(pl->store), &iter_child, PL_COL_DATA, &data, -1); if (IS_PL_ACTIVE(data)) { cflag = 1; break; } } } break; } } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(pl->store), &iter)); if (flag) { if (cflag) { set_cursor_in_playlist(pl, &iter_child, TRUE); } else { set_cursor_in_playlist(pl, &iter, TRUE); } } } } void expand_collapse_album_node(playlist_t * pl) { GtkTreeIter iter, iter_child; gint i, j; GtkTreePath *path; i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(pl->store), &iter, NULL, i++)) { if (gtk_tree_selection_iter_is_selected(pl->select, &iter) && gtk_tree_model_iter_n_children(GTK_TREE_MODEL(pl->store), &iter)) { gtk_tree_view_get_cursor(GTK_TREE_VIEW(pl->view), &path, NULL); if (path && gtk_tree_view_row_expanded(GTK_TREE_VIEW(pl->view), path)) { gtk_tree_view_collapse_row(GTK_TREE_VIEW(pl->view), path); } else { gtk_tree_view_expand_row(GTK_TREE_VIEW(pl->view), path, FALSE); } continue; } j = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(pl->store), &iter_child, &iter, j++)) { if (gtk_tree_selection_iter_is_selected(pl->select, &iter_child) && gtk_tree_model_iter_parent(GTK_TREE_MODEL(pl->store), &iter, &iter_child)) { path = gtk_tree_model_get_path (GTK_TREE_MODEL(pl->store), &iter); if (path) { gtk_tree_view_collapse_row(GTK_TREE_VIEW(pl->view), path); gtk_tree_view_set_cursor(GTK_TREE_VIEW(pl->view), path, NULL, FALSE); } } } } } static gboolean pl_progress_bar_update(gpointer data) { playlist_t * pl = (playlist_t *)data; if (pl->progbar != NULL) { gtk_progress_bar_pulse(GTK_PROGRESS_BAR(pl->progbar)); return TRUE; } return FALSE; } static void pl_progress_bar_stop_clicked(GtkWidget * widget, gpointer data) { playlist_t * pl = (playlist_t *)data; pl->thread_stop = 1; } void playlist_progress_bar_show(playlist_t * pl) { pl->progbar_semaphore++; if (pl->progbar != NULL) { return; } pl->thread_stop = 0; playlist_stats_set_busy(); pl->progbar = gtk_progress_bar_new(); gtk_box_pack_start(GTK_BOX(pl->progbar_container), pl->progbar, TRUE, TRUE, 0); pl->progbar_stop_button = gtk_button_new_with_label(_("Stop adding files")); gtk_box_pack_start(GTK_BOX(pl->progbar_container), pl->progbar_stop_button, FALSE, FALSE, 0); g_signal_connect(G_OBJECT(pl->progbar_stop_button), "clicked", G_CALLBACK(pl_progress_bar_stop_clicked), pl); gtk_widget_show_all(pl->progbar_container); aqualung_timeout_add(200, pl_progress_bar_update, pl); } void playlist_progress_bar_hide(playlist_t * pl) { if (pl->progbar != NULL) { gtk_widget_destroy(pl->progbar); pl->progbar = NULL; } if (pl->progbar_stop_button != NULL) { gtk_widget_destroy(pl->progbar_stop_button); pl->progbar_stop_button = NULL; } } void playlist_progress_bar_hide_all() { GList * list; for (list = playlists; list; list = list->next) { playlist_progress_bar_hide((playlist_t *)list->data); } } int playlist_unlink_files_foreach(playlist_t * pl, GtkTreeIter * iter, void * data) { playlist_data_t * pldata; gtk_tree_model_get(GTK_TREE_MODEL(pl->store), iter, PL_COL_DATA, &pldata, -1); if (g_file_test(pldata->file, G_FILE_TEST_EXISTS)) { GtkListStore * store = (GtkListStore *)data; GtkTreeIter i; gtk_list_store_append(store, &i); gtk_list_store_set(store, &i, 0, pldata->file, 1, gtk_tree_iter_copy(iter), -1); } return 0; } void playlist_unlink_files(playlist_t * pl) { GtkWidget * view; GtkWidget * scrwin; GtkWidget * viewport; GtkCellRenderer * cell; GtkTreeViewColumn * column; GtkListStore * store; GtkTreeIter iter; int res; int i; int error = 0; store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_POINTER); playlist_foreach_selected(pl, playlist_unlink_files_foreach, store); if (gtk_tree_model_iter_n_children(GTK_TREE_MODEL(store), NULL) == 0) { return; } view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store)); cell = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes(_("Files selected for removal"), cell, "text", 0, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(view), GTK_TREE_VIEW_COLUMN(column)); viewport = gtk_viewport_new(NULL, NULL); scrwin = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrwin), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_widget_set_size_request(scrwin, -1, 200); gtk_container_add(GTK_CONTAINER(viewport), scrwin); gtk_container_add(GTK_CONTAINER(scrwin), view); res = message_dialog(_("Remove files"), options.playlist_is_embedded ? main_window : playlist_window, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, viewport, _("The selected files will be deleted from the filesystem. " "No recovery will be possible after this operation.\n\n" "Do you want to proceed?")); i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(store), &iter, NULL, i++)) { GtkTreeIter * pl_iter; gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, 1, &pl_iter, -1); if (res == GTK_RESPONSE_YES) { gchar * file; gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, 0, &file, -1); if (unlink(file) != 0) { fprintf(stderr, "unlink: unable to unlink %s\n", file); perror("unlink"); gtk_tree_selection_unselect_iter(pl->select, pl_iter); ++error; } g_free(file); } gtk_tree_iter_free(pl_iter); } if (res == GTK_RESPONSE_YES) { rem__sel_cb(pl); } if (error) { message_dialog(_("Remove files"), options.playlist_is_embedded ? main_window : playlist_window, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, NULL, (error == 1) ? _("Unable to remove %d file.") : _("Unable to remove %d files."), error); } } void set_cursor_in_playlist(playlist_t * pl, GtkTreeIter *iter, gboolean scroll) { GtkTreePath * visible_path; visible_path = gtk_tree_model_get_path(GTK_TREE_MODEL(pl->store), iter); if (visible_path) { gtk_tree_view_set_cursor(GTK_TREE_VIEW(pl->view), visible_path, NULL, FALSE); if (scroll == TRUE) { gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW (pl->view), visible_path, NULL, TRUE, 0.5, 0.0); } gtk_tree_path_free(visible_path); } } void select_active_position_in_playlist(playlist_t * pl) { GtkTreeIter iter; playlist_data_t * data; if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(pl->store), &iter)) { do { gtk_tree_model_get(GTK_TREE_MODEL(pl->store), &iter, PL_COL_DATA, &data, -1); if (IS_PL_ACTIVE(data)) { set_cursor_in_playlist(pl, &iter, FALSE); break; } } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(pl->store), &iter)); } } void roll_to_active_track(playlist_t * pl, GtkTreeIter * piter) { GtkTreePath * active_path; active_path = gtk_tree_model_get_path(GTK_TREE_MODEL(pl->store), piter); if (active_path) { gtk_tree_view_expand_to_path(GTK_TREE_VIEW(pl->view), active_path); gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(pl->view), active_path, NULL, TRUE, 0.5, 0.0); } gtk_tree_path_free(active_path); } // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/plugin.h0000644000175000001440000000326310612341733013354 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: plugin.h 524 2007-01-06 15:39:18Z pasp $ */ #ifndef _PLUGIN_H #define _PLUGIN_H #include #ifdef HAVE_LADSPA #include #include #include "trashlist.h" #define MAX_PLUGINS 128 #define MAX_KNOBS 128 typedef struct { char filename[MAXLEN]; int index; void * library; int is_restored; int is_mono; int is_bypassed; int shift_pressed; const LADSPA_Descriptor * descriptor; LADSPA_Handle * handle; LADSPA_Handle * handle2; GtkWidget * window; GtkWidget * bypass_button; gint timeout; GtkAdjustment * adjustments[MAX_KNOBS]; LADSPA_Data knobs[MAX_KNOBS]; trashlist_t * trashlist; } plugin_instance; void create_fxbuilder(void); void show_fxbuilder(void); void hide_fxbuilder(void); void save_plugin_data(void); void load_plugin_data(void); #endif /* HAVE_LADSPA */ #endif /* _PLUGIN_H */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/plugin.c0000644000175000001440000020421110736426776013365 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: plugin.c 973 2008-01-01 11:16:27Z peterszilagyi $ */ #include #ifdef HAVE_LADSPA #include #include #include #include #include #include #include #include #include #include #include "common.h" #include "utils_gui.h" #include "i18n.h" #include "options.h" #include "trashlist.h" #include "plugin.h" #ifdef __FreeBSD__ #define dirent64 dirent #define scandir64 scandir #define alphasort64 alphasort #endif /* __FreeBSD__ */ extern options_t options; extern volatile int plugin_lock; extern int n_plugins; extern plugin_instance * plugin_vect[MAX_PLUGINS]; extern unsigned long ladspa_buflen; extern LADSPA_Data * l_buf; extern LADSPA_Data * r_buf; extern unsigned long out_SR; int fxbuilder_on; GtkWidget * fxbuilder_window; GtkWidget * avail_list; GtkListStore * avail_store = NULL; GtkTreeSelection * avail_select; GtkWidget * running_list; GtkListStore * running_store = NULL; GtkTreeSelection * running_select; GtkWidget * add_button; GtkWidget * remove_button; GtkWidget * conf_button; GtkWidget * rp_menu; GtkWidget * scrolled_win_running; extern GtkWidget * plugin_toggle; typedef struct { plugin_instance * instance; int index; } optdata_t; typedef struct { plugin_instance * instance; float start; } btnpdata_t; int added_plugin = 0; void set_active_state(void) { GtkTreeIter iter; if (!gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(running_store), &iter, NULL, 0)) { /* disable buttons and menu */ gtk_widget_set_sensitive(remove_button, FALSE); gtk_widget_set_sensitive(conf_button, FALSE); } else { /* enable buttons and menu */ gtk_widget_set_sensitive(remove_button, TRUE); gtk_widget_set_sensitive(conf_button, TRUE); } } static int rdf_filter(const struct dirent64 * de) { if (de->d_type != DT_UNKNOWN && de->d_type != DT_REG && de->d_type != DT_LNK) return 0; if (de->d_name[0] == '.') return 0; return (((strlen(de->d_name) >= 4) && (strcmp(de->d_name + strlen(de->d_name) - 3, ".n3") == 0)) || ((strlen(de->d_name) >= 5) && (strcmp(de->d_name + strlen(de->d_name) - 4, ".rdf") == 0)) || ((strlen(de->d_name) >= 6) && (strcmp(de->d_name + strlen(de->d_name) - 5, ".rdfs") == 0))); } static int so_filter(const struct dirent64 * de) { if (de->d_type != DT_UNKNOWN && de->d_type != DT_REG && de->d_type != DT_LNK) return 0; if (de->d_name[0] == '.') return 0; return ((strlen(de->d_name) >= 4) && (strcmp(de->d_name + strlen(de->d_name) - 3, ".so") == 0)); } void parse_lrdf_data(void) { char * str; char lrdf_path[MAXLEN]; char rdf_path[MAXLEN]; char fileuri[MAXLEN]; int i, j = 0; struct dirent64 ** de; int n; lrdf_path[0] = '\0'; if ((str = getenv("LADSPA_RDF_PATH"))) { snprintf(lrdf_path, MAXLEN-1, "%s:", str); } else { strncat(lrdf_path, "/usr/local/share/ladspa/rdf:/usr/share/ladspa/rdf:", MAXLEN-1); } for (i = 0; lrdf_path[i] != '\0'; i++) { if (lrdf_path[i] == ':') { rdf_path[j] = '\0'; j = 0; n = scandir64(rdf_path, &de, rdf_filter, alphasort64); if (n >= 0) { int c; for (c = 0; c < n; ++c) { snprintf(fileuri, MAXLEN-1, "file://%s/%s", rdf_path, de[c]->d_name); if (lrdf_read_file(fileuri)) { fprintf(stderr, "warning: could not parse RDF file: %s\n", fileuri); } free(de[c]); } free(de); } } else { rdf_path[j++] = lrdf_path[i]; } } } void get_ladspa_category(unsigned long plugin_id, char * str) { char buf[256]; lrdf_statement pattern; lrdf_statement * matches1; lrdf_statement * matches2; snprintf(buf, 255, "%s%lu", LADSPA_BASE, plugin_id); pattern.subject = buf; pattern.predicate = RDF_TYPE; pattern.object = 0; pattern.object_type = lrdf_uri; matches1 = lrdf_matches(&pattern); if (!matches1) { strncpy(str, "Unknown", MAXLEN-1); return; } pattern.subject = matches1->object; pattern.predicate = LADSPA_BASE "hasLabel"; pattern.object = 0; pattern.object_type = lrdf_literal; matches2 = lrdf_matches (&pattern); lrdf_free_statements(matches1); if (!matches2) { strncpy(str, "Unknown", MAXLEN-1); return; } strncpy(str, matches2->object, MAXLEN-1); lrdf_free_statements(matches2); } static void find_plugins(char * path_entry) { void * library = NULL; char lib_name[MAXLEN]; LADSPA_Descriptor_Function descriptor_fn; const LADSPA_Descriptor * descriptor; struct dirent64 ** de; int n, k, c; long int port, n_ins, n_outs; GtkTreeIter iter; char id_str[32]; char n_ins_str[32]; char n_outs_str[32]; char c_str[32]; char category[MAXLEN]; n = scandir64(path_entry, &de, so_filter, alphasort64); if (n >= 0) { for (c = 0; c < n; ++c) { snprintf(lib_name, MAXLEN-1, "%s/%s", path_entry, de[c]->d_name); library = dlopen(lib_name, RTLD_LAZY); if (library == NULL) { free(de[c]); continue; } descriptor_fn = dlsym(library, "ladspa_descriptor"); if (descriptor_fn == NULL) { free(de[c]); dlclose(library); continue; } for (k = 0; ; ++k) { descriptor = descriptor_fn(k); if (descriptor == NULL) { break; } for (n_ins = n_outs = port = 0; port < descriptor->PortCount; ++port) { if (LADSPA_IS_PORT_AUDIO(descriptor->PortDescriptors[port])) { if (LADSPA_IS_PORT_INPUT(descriptor->PortDescriptors[port])) ++n_ins; if (LADSPA_IS_PORT_OUTPUT(descriptor->PortDescriptors[port])) ++n_outs; } } if ((n_ins == 1 && n_outs == 1) || (n_ins == 2 && n_outs == 2)) { get_ladspa_category(descriptor->UniqueID, category); snprintf(id_str, 31, "%ld", descriptor->UniqueID); snprintf(n_ins_str, 31, "%ld", n_ins); snprintf(n_outs_str, 31, "%ld", n_outs); snprintf(c_str, 31, "%d", k); gtk_list_store_append(avail_store, &iter); gtk_list_store_set(avail_store, &iter, 0, id_str, 1, descriptor->Name, 2, category, 3, n_ins_str, 4, n_outs_str, 5, lib_name, 6, c_str, -1); } } dlclose(library); free(de[c]); } free(de); } } static void find_all_plugins(void) { char * ladspa_path; char * directory; if (!(ladspa_path = getenv("LADSPA_PATH"))) { find_plugins("/usr/lib/ladspa"); find_plugins("/usr/local/lib/ladspa"); } else { ladspa_path = strdup(ladspa_path); directory = strtok(ladspa_path, ":"); while (directory != NULL) { find_plugins(directory); directory = strtok(NULL, ":"); } free(ladspa_path); } } static gboolean fxbuilder_close(GtkWidget * widget, GdkEvent * event, gpointer data) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(plugin_toggle), FALSE); return TRUE; } void show_fxbuilder(void) { set_active_state(); gtk_widget_show_all(fxbuilder_window); fxbuilder_on = 1; register_toplevel_window(fxbuilder_window, TOP_WIN_SKIN | TOP_WIN_TRAY); } void hide_fxbuilder(void) { gtk_widget_hide(fxbuilder_window); fxbuilder_on = 0; register_toplevel_window(fxbuilder_window, TOP_WIN_SKIN); } gint fxbuilder_key_pressed(GtkWidget * widget, GdkEventKey * event, gpointer * data) { switch (event->keyval) { case GDK_q: case GDK_Q: case GDK_Escape: fxbuilder_close(NULL, NULL, NULL); return TRUE; }; return FALSE; } /* we need this because the default gtk sort func doesn't obey spaces in strings eg. "ABCE" gets in between "ABC D" and "ABC F" and not after them. */ gint compare_func(GtkTreeModel * model, GtkTreeIter * a, GtkTreeIter * b, gpointer user_data) { int col = (int) user_data; char * sa; char * sb; int ret; gtk_tree_model_get(model, a, col, &sa, -1); gtk_tree_model_get(model, b, col, &sb, -1); ret = strcmp(sa, sb); g_free(sa); g_free(sb); return ret; } plugin_instance * instantiate(char * filename, int index) { LADSPA_Descriptor_Function descriptor_fn; plugin_instance * instance; int n_ins, n_outs, n_ctrl, port; if ((instance = calloc(1, sizeof(plugin_instance))) == NULL) { fprintf(stderr, "plugin.c: instantiate(): calloc error\n"); return NULL; } strncpy(instance->filename, filename, MAXLEN-1); instance->index = index; instance->library = dlopen(filename, RTLD_NOW); if (instance->library == NULL) { fprintf(stderr, "dlopen() failed on %s -- is it a valid shared library file?\n", filename); free(instance); return NULL; } descriptor_fn = dlsym(instance->library, "ladspa_descriptor"); if (descriptor_fn == NULL) { fprintf(stderr, "dlsym() failed to load symbol 'ladspa_descriptor'. " "Possibly a bug in %s\n", filename); dlclose(instance->library); free(instance); return NULL; } instance->descriptor = descriptor_fn(index); if (LADSPA_IS_INPLACE_BROKEN(instance->descriptor->Properties)) { fprintf(stderr, "%s (%s) is INPLACE_BROKEN and thus unusable in " "Aqualung at this time.\n", instance->descriptor->Label, instance->descriptor->Name); dlclose(instance->library); free(instance); return NULL; } for (n_ins = n_outs = n_ctrl = port = 0; port < instance->descriptor->PortCount; ++port) { if (LADSPA_IS_PORT_AUDIO(instance->descriptor->PortDescriptors[port])) { if (LADSPA_IS_PORT_INPUT(instance->descriptor->PortDescriptors[port])) ++n_ins; if (LADSPA_IS_PORT_OUTPUT(instance->descriptor->PortDescriptors[port])) ++n_outs; } else { ++n_ctrl; } } if (n_ctrl > MAX_KNOBS) { fprintf(stderr, "%s (%s) has more than %d input knobs; " "Aqualung cannot use it.\n", instance->descriptor->Label, instance->descriptor->Name, MAX_KNOBS); dlclose(instance->library); free(instance); return NULL; } if ((n_ins == 1) && (n_outs == 1)) { instance->is_mono = 1; instance->handle = instance->descriptor->instantiate(instance->descriptor, out_SR); instance->handle2 = instance->descriptor->instantiate(instance->descriptor, out_SR); } else { instance->is_mono = 0; instance->handle = instance->descriptor->instantiate(instance->descriptor, out_SR); instance->handle2 = NULL; } instance->is_restored = 0; instance->is_bypassed = 1; instance->shift_pressed = 0; instance->window = NULL; instance->bypass_button = NULL; instance->trashlist = trashlist_new(); return instance; } void connect_port(plugin_instance * instance) { unsigned long port; unsigned long inputs = 0, outputs = 0; const LADSPA_Descriptor * plugin = instance->descriptor; for (port = 0; port < plugin->PortCount; ++port) { if (LADSPA_IS_PORT_CONTROL(plugin->PortDescriptors[port])) { if (port < MAX_KNOBS) { plugin->connect_port(instance->handle, port, &(instance->knobs[port])); if (instance->handle2) plugin->connect_port(instance->handle2, port, &(instance->knobs[port])); } else { fprintf(stderr, "impossible: control port count out of range\n"); } } else if (LADSPA_IS_PORT_AUDIO(plugin->PortDescriptors[port])) { if (LADSPA_IS_PORT_INPUT(plugin->PortDescriptors[port])) { if (inputs == 0) { plugin->connect_port(instance->handle, port, l_buf); if (instance->handle2) plugin->connect_port(instance->handle2, port, r_buf); } else if (inputs == 1 && !instance->is_mono) { plugin->connect_port(instance->handle, port, r_buf); } else { fprintf(stderr, "impossible: input port count out of range\n"); } inputs++; } else if (LADSPA_IS_PORT_OUTPUT(plugin->PortDescriptors[port])) { if (outputs == 0) { plugin->connect_port(instance->handle, port, l_buf); if (instance->handle2) plugin->connect_port(instance->handle2, port, r_buf); } else if (outputs == 1 && !instance->is_mono) { plugin->connect_port(instance->handle, port, r_buf); } else { fprintf(stderr, "impossible: output port count out of range\n"); } outputs++; } } } } void activate(plugin_instance * instance) { const LADSPA_Descriptor * descriptor = instance->descriptor; if (descriptor->activate) { descriptor->activate(instance->handle); if (instance->handle2) { descriptor->activate(instance->handle2); } } } void get_bypassed_name(plugin_instance * instance, char * str) { if (instance->is_bypassed) { snprintf(str, MAXLEN-1, "(%s)", instance->descriptor->Name); } else { strncpy(str, instance->descriptor->Name, MAXLEN-1); } } void refresh_plugin_vect(int diff) { int i = 0, j = 0; GtkTreeIter iter; gpointer gp_instance; plugin_instance * plugin_vect_shadow[MAX_PLUGINS]; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(running_store), &iter, NULL, i) && i < MAX_PLUGINS) { gtk_tree_model_get(GTK_TREE_MODEL(running_store), &iter, 1, &gp_instance, -1); plugin_vect_shadow[i] = (plugin_instance *) gp_instance; ++i; } while (plugin_lock) ; if (diff < 0) n_plugins += diff; for (j = 0; j < i; j++) { while (plugin_lock) ; plugin_vect[j] = plugin_vect_shadow[j]; } while (plugin_lock) ; if (diff >= 0) n_plugins += diff; } static gboolean close_plugin_window(GtkWidget * widget, GdkEvent * event, gpointer data) { gtk_widget_hide(widget); register_toplevel_window(widget, TOP_WIN_SKIN); return TRUE; } void plugin_bypassed(GtkWidget * widget, gpointer data) { int i = 0; GtkTreeIter iter; char bypassed_name[MAXLEN]; char * name; gpointer gp_instance; plugin_instance * instance = (plugin_instance *) data; if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) { instance->is_bypassed = 1; } else { instance->is_bypassed = 0; } while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(running_store), &iter, NULL, i)) { gtk_tree_model_get(GTK_TREE_MODEL(running_store), &iter, 0, &name, 1, &gp_instance, -1); if (instance == (plugin_instance *)gp_instance) { get_bypassed_name(instance, bypassed_name); gtk_list_store_set(running_store, &iter, 0, bypassed_name, -1); return; } ++i; } } void plugin_btn_toggled(GtkWidget * widget, gpointer data) { LADSPA_Data * plugin_data = (LADSPA_Data *) data; if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) { *plugin_data = 1.0f; } else { *plugin_data = -1.0f; } } gint update_plugin_outputs(gpointer data) { plugin_instance * instance = (plugin_instance *) data; unsigned long k; for (k = 0; k < MAX_KNOBS && k < instance->descriptor->PortCount; ++k) { if (LADSPA_IS_PORT_OUTPUT(instance->descriptor->PortDescriptors[k]) && LADSPA_IS_PORT_CONTROL(instance->descriptor->PortDescriptors[k])) { while (plugin_lock) ; instance->adjustments[k]->value = instance->knobs[k]; } } for (k = 0; k < MAX_KNOBS && k < instance->descriptor->PortCount; ++k) { if (LADSPA_IS_PORT_OUTPUT(instance->descriptor->PortDescriptors[k]) && LADSPA_IS_PORT_CONTROL(instance->descriptor->PortDescriptors[k])) { gtk_adjustment_value_changed(instance->adjustments[k]); } } return TRUE; } void plugin_value_changed(GtkAdjustment * adj, gpointer data) { LADSPA_Data * plugin_data = (LADSPA_Data *) data; *plugin_data = (LADSPA_Data) gtk_adjustment_get_value(adj); } void changed_combo(GtkWidget * widget, gpointer * data) { optdata_t * optdata = (optdata_t *) data; plugin_instance * instance = optdata->instance; int k = optdata->index; int i = gtk_combo_box_get_active(GTK_COMBO_BOX(widget)); LADSPA_Data value = 0.0f; lrdf_defaults * defs = lrdf_get_scale_values(instance->descriptor->UniqueID, k); value = defs->items[i].value; lrdf_free_setting_values(defs); instance->knobs[k] = value; } gint plugin_window_key_pressed(GtkWidget * widget, GdkEventKey * event, gpointer * data) { plugin_instance * instance = (plugin_instance *) data; switch (event->keyval) { case GDK_Shift_L: case GDK_Shift_R: instance->shift_pressed = 1; break; } return FALSE; } gint plugin_window_key_released(GtkWidget * widget, GdkEventKey * event, gpointer * data) { plugin_instance * instance = (plugin_instance *) data; switch (event->keyval) { case GDK_Shift_L: case GDK_Shift_R: instance->shift_pressed = 0; break; } return FALSE; } gint plugin_window_focus_out(GtkWidget * widget, GdkEventKey * event, gpointer * data) { plugin_instance * instance = (plugin_instance *) data; instance->shift_pressed = 0; return FALSE; } gint plugin_scale_btn_pressed(GtkWidget * widget, GdkEventButton * event, gpointer * data) { btnpdata_t * btnpdata = (btnpdata_t *) data; GtkAdjustment * adj; if (event->button != 1) return FALSE; if (!btnpdata->instance->shift_pressed) return FALSE; adj = gtk_range_get_adjustment(GTK_RANGE(widget)); adj->value = btnpdata->start; gtk_adjustment_value_changed(adj); return TRUE; } void build_plugin_window(plugin_instance * instance) { const LADSPA_Descriptor * plugin = instance->descriptor; const LADSPA_PortRangeHint * hints = plugin->PortRangeHints; LADSPA_Data fact, min, max, step, start, default_val; lrdf_defaults * defs; int dp; unsigned long k; int n_outs = 0; int n_ins = 0; int n_toggled = 0; int n_untoggled = 0; int n_outctl = 0; int n_outlat = 0; int n_rows = 0; int i = 0; char str_inout[32]; char str_n[16]; char * c; char maker[MAXLEN]; GtkWidget * widget; GtkWidget * hbox; GtkWidget * vbox; GtkWidget * upper_hbox; GtkWidget * upper_vbox; GtkWidget * scrwin; GtkWidget * inner_vbox; GtkWidget * table = NULL; GtkWidget * hseparator; GtkObject * adjustment; GtkWidget * combo; GList * glist; optdata_t * optdata; btnpdata_t * btnpdata; int j; GtkRequisition req; int max_width = 0; int height = 0; instance->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(instance->window), plugin->Name); gtk_window_set_position(GTK_WINDOW(instance->window), GTK_WIN_POS_CENTER); gtk_window_set_transient_for(GTK_WINDOW(instance->window), GTK_WINDOW(fxbuilder_window)); g_signal_connect(G_OBJECT(instance->window), "key_press_event", G_CALLBACK(plugin_window_key_pressed), instance); g_signal_connect(G_OBJECT(instance->window), "key_release_event", G_CALLBACK(plugin_window_key_released), instance); g_signal_connect(G_OBJECT(instance->window), "focus_out_event", G_CALLBACK(plugin_window_focus_out), instance); gtk_widget_set_events(instance->window, GDK_BUTTON_PRESS_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK); gtk_container_set_border_width(GTK_CONTAINER(instance->window), 5); vbox = gtk_vbox_new(FALSE, 3); gtk_container_add(GTK_CONTAINER(instance->window), vbox); upper_hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox), upper_hbox, FALSE, TRUE, 2); upper_vbox = gtk_vbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(upper_hbox), upper_vbox, FALSE, FALSE, 2); widget = gtk_label_new(plugin->Name); gtk_widget_set_name(widget, "plugin_name"); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(upper_vbox), hbox, FALSE, FALSE, 2); strncpy(maker, plugin->Maker, MAXLEN-1); if ((c = strchr(maker, '<')) != NULL) *c = '\0'; widget = gtk_label_new(maker); gtk_widget_set_name(widget, "plugin_maker"); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(upper_vbox), hbox, FALSE, FALSE, 2); /* count audio I/O ports */ for (k = 0; k < MAX_KNOBS && k < plugin->PortCount; ++k) { if (LADSPA_IS_PORT_CONTROL(plugin->PortDescriptors[k])) continue; if (LADSPA_IS_PORT_OUTPUT(plugin->PortDescriptors[k])) { ++n_outs; } else { ++n_ins; } } strcpy(str_inout, "[ "); if (n_ins == 1) { strcat(str_inout, "1 in"); } else { snprintf(str_n, 15, "%d ins", n_ins); strcat(str_inout, str_n); } strcat(str_inout, " | "); if (n_outs == 1) { strcat(str_inout, "1 out"); } else { snprintf(str_n, 15, "%d outs", n_outs); strcat(str_inout, str_n); } strcat(str_inout, " ]"); widget = gtk_label_new(str_inout); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(upper_vbox), hbox, FALSE, FALSE, 2); upper_vbox = gtk_vbox_new(FALSE, 0); gtk_box_pack_end(GTK_BOX(upper_hbox), upper_vbox, FALSE, FALSE, 2); widget = gtk_toggle_button_new_with_label("BYPASS"); gtk_widget_set_name(widget, "plugin_bypass_button"); instance->bypass_button = widget; gtk_box_pack_start(GTK_BOX(upper_vbox), widget, FALSE, FALSE, 2); g_signal_connect(G_OBJECT(widget), "toggled", G_CALLBACK(plugin_bypassed), instance); if (instance->is_restored) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), instance->is_bypassed); } else { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), TRUE); } /* count control I/O ports */ for (k = 0; k < MAX_KNOBS && k < plugin->PortCount; ++k) { if (LADSPA_IS_PORT_AUDIO(plugin->PortDescriptors[k])) continue; if (LADSPA_IS_PORT_INPUT(plugin->PortDescriptors[k])) { if (LADSPA_IS_HINT_TOGGLED(hints[k].HintDescriptor)) { ++n_toggled; } else { ++n_untoggled; } } else { if (strcmp(plugin->PortNames[k], "latency") == 0) { ++n_outlat; } else { ++n_outctl; } } ++n_rows; } if ((n_toggled) && (n_untoggled)) ++n_rows; if (((n_toggled) || (n_untoggled)) && (n_outctl)) ++n_rows; if (((n_toggled) || (n_untoggled) || (n_outctl)) && (n_outlat)) ++n_rows; scrwin = gtk_scrolled_window_new(NULL, NULL); gtk_widget_set_name(scrwin, "plugin_scrwin"); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrwin), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_box_pack_start(GTK_BOX(vbox), scrwin, TRUE, TRUE, 2); inner_vbox = gtk_vbox_new(FALSE, 0); gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrwin), inner_vbox); if ((n_toggled) || (n_untoggled) || (n_outctl) || (n_outlat)) { table = gtk_table_new(n_rows, 3, FALSE); gtk_box_pack_start(GTK_BOX(inner_vbox), table, TRUE, TRUE, 2); } if (n_toggled) { for (k = 0; k < MAX_KNOBS && k < plugin->PortCount; ++k) { int max_height = 0; if (!LADSPA_IS_PORT_CONTROL(plugin->PortDescriptors[k])) continue; if (LADSPA_IS_PORT_OUTPUT(plugin->PortDescriptors[k])) continue; if (!LADSPA_IS_HINT_TOGGLED(hints[k].HintDescriptor)) continue; widget = gtk_label_new(plugin->PortNames[k]); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(table), hbox, 0, 1, i, i+1, GTK_FILL, GTK_FILL | GTK_EXPAND, 2, 2); gtk_widget_size_request(widget, &req); req.height += 2; if (req.width > max_width) max_width = req.width; if (req.height > max_height) max_height = req.height; widget = gtk_toggle_button_new(); gtk_widget_set_name(widget, "plugin_toggled"); gtk_widget_set_size_request(widget, 14, 14); gtk_table_attach(GTK_TABLE(table), widget, 2, 3, i, i+1, 0, 0, 0, 0); gtk_widget_size_request(widget, &req); if (req.height > max_height) max_height = req.height; height += max_height; ++i; g_signal_connect(G_OBJECT(widget), "toggled", G_CALLBACK(plugin_btn_toggled), &(instance->knobs[k])); if (((instance->is_restored) && (instance->knobs[k] > 0.0f)) || ((!instance->is_restored) && (LADSPA_IS_HINT_DEFAULT_1(hints[k].HintDescriptor)))) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), TRUE); } } } if ((n_toggled) && (n_untoggled)) { hseparator = gtk_hseparator_new(); gtk_table_attach(GTK_TABLE(table), hseparator, 0, 3, i, i+1, GTK_FILL, GTK_FILL, 2, 2); ++i; gtk_widget_size_request(hseparator, &req); height += req.height + 5; } if (n_untoggled) { for (k = 0; k < MAX_KNOBS && k < plugin->PortCount; ++k) { int max_height = 0; if (!LADSPA_IS_PORT_CONTROL(plugin->PortDescriptors[k])) continue; if (LADSPA_IS_PORT_OUTPUT(plugin->PortDescriptors[k])) continue; if (LADSPA_IS_HINT_TOGGLED(hints[k].HintDescriptor)) continue; widget = gtk_label_new(plugin->PortNames[k]); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(table), hbox, 0, 1, i, i+1, GTK_FILL, GTK_FILL | GTK_EXPAND, 2, 2); gtk_widget_size_request(widget, &req); req.height += 2; if (req.width > max_width) max_width = req.width; if (LADSPA_IS_HINT_SAMPLE_RATE(hints[k].HintDescriptor)) { fact = out_SR; } else { fact = 1.0f; } if (LADSPA_IS_HINT_BOUNDED_BELOW(hints[k].HintDescriptor)) { min = hints[k].LowerBound * fact; } else { min = -10000.0f; } if (LADSPA_IS_HINT_BOUNDED_ABOVE(hints[k].HintDescriptor)) { max = hints[k].UpperBound * fact; } else { max = 10000.0f; } /* infinity */ if (10000.0f <= max - min) { dp = 1; step = 5.0f; /* 100.0 ... lots */ } else if (100.0f < max - min) { dp = 0; step = 1.0f; /* 10.0 ... 100.0 */ } else if (10.0f < max - min) { dp = 1; step = 0.1f; /* 1.0 ... 10.0 */ } else if (1.0f < max - min) { dp = 2; step = 0.01f; /* 0.0 ... 1.0 */ } else { dp = 3; step = 0.001f; } if (LADSPA_IS_HINT_INTEGER(hints[k].HintDescriptor)) { dp = 0; if (step < 1.0f) step = 1.0f; } if (LADSPA_IS_HINT_DEFAULT_MINIMUM(hints[k].HintDescriptor)) { default_val = min; } else if (LADSPA_IS_HINT_DEFAULT_LOW(hints[k].HintDescriptor)) { default_val = min * 0.75f + max * 0.25f; } else if (LADSPA_IS_HINT_DEFAULT_MIDDLE(hints[k].HintDescriptor)) { default_val = min * 0.5f + max * 0.5f; } else if (LADSPA_IS_HINT_DEFAULT_HIGH(hints[k].HintDescriptor)) { default_val = min * 0.25f + max * 0.75f; } else if (LADSPA_IS_HINT_DEFAULT_MAXIMUM(hints[k].HintDescriptor)) { default_val = max; } else if (LADSPA_IS_HINT_DEFAULT_0(hints[k].HintDescriptor)) { default_val = 0.0f; } else if (LADSPA_IS_HINT_DEFAULT_1(hints[k].HintDescriptor)) { default_val = 1.0f; } else if (LADSPA_IS_HINT_DEFAULT_100(hints[k].HintDescriptor)) { default_val = 100.0f; } else if (LADSPA_IS_HINT_DEFAULT_440(hints[k].HintDescriptor)) { default_val = 440.0f; } else if (LADSPA_IS_HINT_INTEGER(hints[k].HintDescriptor)) { default_val = min; } else if (max >= 0.0f && min <= 0.0f) { default_val = 0.0f; } else { default_val = min * 0.5f + max * 0.5f; } if (instance->is_restored) { start = instance->knobs[k]; } else { instance->knobs[k] = start = default_val; } defs = lrdf_get_scale_values(plugin->UniqueID, k); if ((defs) && (defs->count > 0)) { /* have scale values */ combo = gtk_combo_box_new_text (); gtk_widget_set_name(combo, "plugin_combo"); glist = NULL; gtk_table_attach(GTK_TABLE(table), combo, 1, 3, i, i+1, GTK_FILL | GTK_EXPAND, GTK_FILL, 2, 2); for (j = 0; j < defs->count; j++) { gtk_combo_box_append_text (GTK_COMBO_BOX (combo), defs->items[j].label); } gtk_widget_size_request(combo, &req); req.height += 2; if (req.height > max_height) max_height = req.height; /* now if we have an option that corresponds to 'start', choose that. */ for (j = 0; j < defs->count; j++) { if (defs->items[j].value == start) { gtk_combo_box_set_active (GTK_COMBO_BOX (combo), start); break; } } if ((optdata = malloc(sizeof(optdata_t))) == NULL) { fprintf(stderr, "plugin.c: build_plugin_window(): malloc error\n"); return; } trashlist_add(instance->trashlist, optdata); optdata->instance = instance; optdata->index = k; g_signal_connect(combo, "changed", G_CALLBACK(changed_combo), optdata); } else { /* no scale values */ adjustment = gtk_adjustment_new(start, min, max, step, step * 50.0, 0.0); instance->adjustments[k] = GTK_ADJUSTMENT(adjustment); g_signal_connect(G_OBJECT(adjustment), "value_changed", G_CALLBACK(plugin_value_changed), &(instance->knobs[k])); if (!LADSPA_IS_HINT_INTEGER(hints[k].HintDescriptor)) { widget = gtk_hscale_new(GTK_ADJUSTMENT(adjustment)); gtk_widget_set_name(widget, "plugin_scale"); gtk_widget_set_size_request(widget, 200, -1); gtk_scale_set_digits(GTK_SCALE(widget), dp); gtk_table_attach(GTK_TABLE(table), widget, 1, 2, i, i+1, GTK_FILL | GTK_EXPAND, GTK_FILL, 2, 2); gtk_scale_set_draw_value(GTK_SCALE(widget), FALSE); gtk_widget_size_request(widget, &req); req.height += 2; if (req.height > max_height) max_height = req.height; if ((btnpdata = malloc(sizeof(btnpdata_t))) == NULL) { fprintf(stderr, "plugin.c: build_plugin_window(): malloc error\n"); return; } trashlist_add(instance->trashlist, btnpdata); btnpdata->instance = instance; btnpdata->start = default_val; g_signal_connect(G_OBJECT(widget), "button_press_event", G_CALLBACK(plugin_scale_btn_pressed), (gpointer) btnpdata); } widget = gtk_spin_button_new(GTK_ADJUSTMENT(adjustment), step, dp); gtk_widget_set_size_request(widget, 70, -1); gtk_table_attach(GTK_TABLE(table), widget, 2, 3, i, i+1, GTK_FILL, GTK_FILL, 2, 2); gtk_widget_size_request(widget, &req); req.height += 2; if (req.height > max_height) max_height = req.height; } height += max_height; ++i; lrdf_free_setting_values(defs); } } if (((n_toggled) || (n_untoggled)) && (n_outctl)) { hseparator = gtk_hseparator_new(); gtk_table_attach(GTK_TABLE(table), hseparator, 0, 3, i, i+1, GTK_FILL, GTK_FILL, 2, 2); ++i; gtk_widget_size_request(hseparator, &req); height += req.height + 5; } if (n_outctl) { for (k = 0; k < MAX_KNOBS && k < plugin->PortCount; ++k) { int max_height = 0; if (!LADSPA_IS_PORT_CONTROL(plugin->PortDescriptors[k])) continue; if (LADSPA_IS_PORT_INPUT(plugin->PortDescriptors[k])) continue; if (LADSPA_IS_HINT_TOGGLED(hints[k].HintDescriptor)) continue; widget = gtk_label_new(plugin->PortNames[k]); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(table), hbox, 0, 1, i, i+1, GTK_FILL, GTK_FILL | GTK_EXPAND, 2, 2); gtk_widget_size_request(widget, &req); req.height += 2; if (req.width > max_width) max_width = req.width; if (req.height > max_height) max_height = req.height; if (LADSPA_IS_HINT_SAMPLE_RATE(hints[k].HintDescriptor)) { fact = out_SR; } else { fact = 1.0f; } if (LADSPA_IS_HINT_BOUNDED_BELOW(hints[k].HintDescriptor)) { min = hints[k].LowerBound * fact; } else { min = -10000.0f; } if (LADSPA_IS_HINT_BOUNDED_ABOVE(hints[k].HintDescriptor)) { max = hints[k].UpperBound * fact; } else { max = 10000.0f; } /* infinity */ if (10000.0f <= max - min) { dp = 1; step = 5.0f; /* 100.0 ... lots */ } else if (100.0f < max - min) { dp = 0; step = 1.0f; /* 10.0 ... 100.0 */ } else if (10.0f < max - min) { dp = 1; step = 0.1f; /* 1.0 ... 10.0 */ } else if (1.0f < max - min) { dp = 2; step = 0.01f; /* 0.0 ... 1.0 */ } else { dp = 3; step = 0.001f; } if (LADSPA_IS_HINT_INTEGER(hints[k].HintDescriptor)) { dp = 0; if (step < 1.0f) step = 1.0f; } if (LADSPA_IS_HINT_DEFAULT_MINIMUM(hints[k].HintDescriptor)) { start = min; } else if (LADSPA_IS_HINT_DEFAULT_LOW(hints[k].HintDescriptor)) { start = min * 0.75f + max * 0.25f; } else if (LADSPA_IS_HINT_DEFAULT_MIDDLE(hints[k].HintDescriptor)) { start = min * 0.5f + max * 0.5f; } else if (LADSPA_IS_HINT_DEFAULT_HIGH(hints[k].HintDescriptor)) { start = min * 0.25f + max * 0.75f; } else if (LADSPA_IS_HINT_DEFAULT_MAXIMUM(hints[k].HintDescriptor)) { start = max; } else if (LADSPA_IS_HINT_DEFAULT_0(hints[k].HintDescriptor)) { start = 0.0f; } else if (LADSPA_IS_HINT_DEFAULT_1(hints[k].HintDescriptor)) { start = 1.0f; } else if (LADSPA_IS_HINT_DEFAULT_100(hints[k].HintDescriptor)) { start = 100.0f; } else if (LADSPA_IS_HINT_DEFAULT_440(hints[k].HintDescriptor)) { start = 440.0f; } else if (LADSPA_IS_HINT_INTEGER(hints[k].HintDescriptor)) { start = min; } else if (max >= 0.0f && min <= 0.0f) { start = 0.0f; } else { start = min * 0.5f + max * 0.5f; } instance->knobs[k] = start; adjustment = gtk_adjustment_new(start, min, max, step, step * 50.0, 0.0); instance->adjustments[k] = GTK_ADJUSTMENT(adjustment); if (!LADSPA_IS_HINT_INTEGER(hints[k].HintDescriptor)) { widget = gtk_hscale_new(GTK_ADJUSTMENT(adjustment)); gtk_widget_set_name(widget, "plugin_scale"); gtk_widget_set_size_request(widget, 200, -1); gtk_scale_set_digits(GTK_SCALE(widget), dp); gtk_table_attach(GTK_TABLE(table), widget, 1, 2, i, i+1, GTK_FILL | GTK_EXPAND, GTK_FILL, 2, 2); gtk_scale_set_draw_value(GTK_SCALE(widget), FALSE); gtk_widget_set_sensitive(widget, FALSE); gtk_widget_size_request(widget, &req); req.height += 2; if (req.height > max_height) max_height = req.height; } widget = gtk_spin_button_new(GTK_ADJUSTMENT(adjustment), step, dp); gtk_widget_set_size_request(widget, 70, -1); gtk_widget_set_sensitive(widget, FALSE); gtk_table_attach(GTK_TABLE(table), widget, 2, 3, i, i+1, GTK_FILL, GTK_FILL, 2, 2); gtk_widget_size_request(widget, &req); req.height += 2; if (req.height > max_height) max_height = req.height; height += max_height; ++i; } } if (((n_toggled) || (n_untoggled) || (n_outctl)) && (n_outlat)) { hseparator = gtk_hseparator_new(); gtk_table_attach(GTK_TABLE(table), hseparator, 0, 3, i, i+1, GTK_FILL, GTK_FILL, 2, 2); ++i; gtk_widget_size_request(hseparator, &req); height += req.height + 5; } if (n_outlat) { for (k = 0; k < MAX_KNOBS && k < plugin->PortCount; ++k) { int max_height = 0; if (!LADSPA_IS_PORT_CONTROL(plugin->PortDescriptors[k])) continue; if (LADSPA_IS_PORT_INPUT(plugin->PortDescriptors[k])) continue; if (LADSPA_IS_HINT_TOGGLED(hints[k].HintDescriptor)) continue; widget = gtk_label_new(plugin->PortNames[k]); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(table), hbox, 0, 1, i, i+1, GTK_FILL, GTK_FILL | GTK_EXPAND, 2, 2); gtk_widget_size_request(widget, &req); req.height += 2; if (req.width > max_width) max_width = req.width; if (req.height > max_height) max_height = req.height; if (LADSPA_IS_HINT_SAMPLE_RATE(hints[k].HintDescriptor)) { fact = out_SR; } else { fact = 1.0f; } if (LADSPA_IS_HINT_BOUNDED_BELOW(hints[k].HintDescriptor)) { min = hints[k].LowerBound * fact; } else { min = -10000.0f; } if (LADSPA_IS_HINT_BOUNDED_ABOVE(hints[k].HintDescriptor)) { max = hints[k].UpperBound * fact; } else { max = 10000.0f; } /* infinity */ if (10000.0f <= max - min) { dp = 1; step = 5.0f; /* 100.0 ... lots */ } else if (100.0f < max - min) { dp = 0; step = 1.0f; /* 10.0 ... 100.0 */ } else if (10.0f < max - min) { dp = 1; step = 0.1f; /* 1.0 ... 10.0 */ } else if (1.0f < max - min) { dp = 2; step = 0.01f; /* 0.0 ... 1.0 */ } else { dp = 3; step = 0.001f; } if (LADSPA_IS_HINT_INTEGER(hints[k].HintDescriptor)) { dp = 0; if (step < 1.0f) step = 1.0f; } if (LADSPA_IS_HINT_DEFAULT_MINIMUM(hints[k].HintDescriptor)) { start = min; } else if (LADSPA_IS_HINT_DEFAULT_LOW(hints[k].HintDescriptor)) { start = min * 0.75f + max * 0.25f; } else if (LADSPA_IS_HINT_DEFAULT_MIDDLE(hints[k].HintDescriptor)) { start = min * 0.5f + max * 0.5f; } else if (LADSPA_IS_HINT_DEFAULT_HIGH(hints[k].HintDescriptor)) { start = min * 0.25f + max * 0.75f; } else if (LADSPA_IS_HINT_DEFAULT_MAXIMUM(hints[k].HintDescriptor)) { start = max; } else if (LADSPA_IS_HINT_DEFAULT_0(hints[k].HintDescriptor)) { start = 0.0f; } else if (LADSPA_IS_HINT_DEFAULT_1(hints[k].HintDescriptor)) { start = 1.0f; } else if (LADSPA_IS_HINT_DEFAULT_100(hints[k].HintDescriptor)) { start = 100.0f; } else if (LADSPA_IS_HINT_DEFAULT_440(hints[k].HintDescriptor)) { start = 440.0f; } else if (LADSPA_IS_HINT_INTEGER(hints[k].HintDescriptor)) { start = min; } else if (max >= 0.0f && min <= 0.0f) { start = 0.0f; } else { start = min * 0.5f + max * 0.5f; } instance->knobs[k] = start; adjustment = gtk_adjustment_new(start, min, max, step, step * 50.0, 0.0); instance->adjustments[k] = GTK_ADJUSTMENT(adjustment); if (!LADSPA_IS_HINT_INTEGER(hints[k].HintDescriptor)) { widget = gtk_hscale_new(GTK_ADJUSTMENT(adjustment)); gtk_widget_set_name(widget, "plugin_scale"); gtk_widget_set_size_request(widget, 200, -1); gtk_scale_set_digits(GTK_SCALE(widget), dp); gtk_table_attach(GTK_TABLE(table), widget, 1, 2, i, i+1, GTK_FILL | GTK_EXPAND, GTK_FILL, 2, 2); gtk_scale_set_draw_value(GTK_SCALE(widget), FALSE); gtk_widget_set_sensitive(widget, FALSE); gtk_widget_size_request(widget, &req); req.height += 2; if (req.height > max_height) max_height = req.height; } widget = gtk_spin_button_new(GTK_ADJUSTMENT(adjustment), step, dp); gtk_widget_set_size_request(widget, 70, -1); gtk_widget_set_sensitive(widget, FALSE); gtk_table_attach(GTK_TABLE(table), widget, 2, 3, i, i+1, GTK_FILL, GTK_FILL, 2, 2); gtk_widget_size_request(widget, &req); req.height += 2; if (req.height > max_height) max_height = req.height; height += max_height; ++i; } } if ((!n_toggled) && (!n_untoggled) && (!n_outctl) && (!n_outlat)) { widget = gtk_label_new("This LADSPA plugin has no user controls"); gtk_box_pack_start(GTK_BOX(inner_vbox), widget, TRUE, TRUE, 2); gtk_widget_size_request(widget, &req); gtk_widget_set_size_request(scrwin, req.width + 20, req.height + 20); } else { gtk_widget_set_size_request(scrwin, (max_width + 280) * 1.1, (height > 500) ? 500 : height * 1.1 + 10); } if ((n_outctl) || (n_outlat)) { instance->timeout = aqualung_timeout_add(100, update_plugin_outputs, instance); } else { instance->timeout = 0; } set_active_state(); g_signal_connect(G_OBJECT(instance->window), "delete_event", G_CALLBACK(close_plugin_window), NULL); } void foreach_plugin_to_add(GtkTreeModel * model, GtkTreePath * path, GtkTreeIter * iter, gpointer data) { GtkTreeIter running_iter; int n_ins; int n_outs; char filename[MAXLEN]; int index; char * str_n_ins; char * str_n_outs; char * str_filename; char * str_index; plugin_instance * instance; char bypassed_name[MAXLEN]; gtk_tree_model_get(GTK_TREE_MODEL(avail_store), iter, 3, &str_n_ins, 4, &str_n_outs, 5, &str_filename, 6, &str_index, -1); sscanf(str_n_ins, "%d", &n_ins); sscanf(str_n_outs, "%d", &n_outs); strncpy(filename, str_filename, MAXLEN-1); sscanf(str_index, "%d", &index); if (((n_ins == 1) && (n_outs == 1)) || ((n_ins == 2) && (n_outs == 2))) { if (n_plugins >= MAX_PLUGINS) { fprintf(stderr, "Maximum number of running plugin instances (%d) reached; " "cannot add more.\n", MAX_PLUGINS); return; } instance = instantiate(filename, index); if (instance) { connect_port(instance); activate(instance); build_plugin_window(instance); get_bypassed_name(instance, bypassed_name); added_plugin = 1; /* so resort handler will not do any harm */ gtk_list_store_append(running_store, &running_iter); gtk_list_store_set(running_store, &running_iter, 0, bypassed_name, 1, (gpointer)instance, -1); refresh_plugin_vect(1); } } else { fprintf(stderr, "cannot add %s:%d -- it has %d ins and %d outs.\n", filename, index, n_ins, n_outs); } } gint add_clicked(GtkWidget * widget, GdkEvent * event, gpointer data) { gtk_tree_selection_selected_foreach(avail_select, foreach_plugin_to_add, NULL); set_active_state(); return TRUE; } gint remove_clicked(GtkWidget * widget, GdkEvent * event, gpointer data) { GtkTreeIter iter; gpointer gp_instance; plugin_instance * instance; if (gtk_tree_selection_get_selected(running_select, NULL, &iter)) { gtk_tree_model_get(GTK_TREE_MODEL(running_store), &iter, 1, &gp_instance, -1); gtk_list_store_remove(running_store, &iter); refresh_plugin_vect(-1); instance = (plugin_instance *) gp_instance; if (instance->handle) { if (instance->descriptor->deactivate) { instance->descriptor->deactivate(instance->handle); } instance->descriptor->cleanup(instance->handle); instance->handle = NULL; } if (instance->handle2) { if (instance->descriptor->deactivate) { instance->descriptor->deactivate(instance->handle2); } instance->descriptor->cleanup(instance->handle2); instance->handle2 = NULL; } if (instance->timeout) { g_source_remove(instance->timeout); } if (instance->window) { gtk_widget_destroy(instance->window); unregister_toplevel_window(instance->window); } dlclose(instance->library); trashlist_free(instance->trashlist); free(instance); } set_active_state(); return TRUE; } gint conf_clicked(GtkWidget * widget, GdkEvent * event, gpointer data) { GtkTreeIter iter; gpointer gp_instance; plugin_instance * instance; if (gtk_tree_selection_get_selected(running_select, NULL, &iter)) { gtk_tree_model_get(GTK_TREE_MODEL(running_store), &iter, 1, &gp_instance, -1); instance = (plugin_instance *) gp_instance; if (instance->window) { register_toplevel_window(instance->window, TOP_WIN_SKIN | TOP_WIN_TRAY); gtk_widget_show_all(instance->window); } } return TRUE; } gint running_list_key_pressed(GtkWidget * widget, GdkEventKey * event) { switch (event->keyval) { case GDK_Delete: case GDK_KP_Delete: remove_clicked(NULL, NULL, NULL); return TRUE; break; } return FALSE; } gint running_list_button_pressed(GtkWidget * widget, GdkEventButton * event) { GtkTreeIter iter; GtkTreePath * path; GtkTreeViewColumn * column; gpointer gp_instance; plugin_instance * instance; if (event->type == GDK_BUTTON_PRESS && event->button == 2) { if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(running_list), event->x, event->y, &path, &column, NULL, NULL)) { gtk_tree_view_set_cursor(GTK_TREE_VIEW(running_list), path, NULL, FALSE); gtk_tree_selection_get_selected(running_select, NULL, &iter); gtk_tree_model_get(GTK_TREE_MODEL(running_store), &iter, 1, &gp_instance, -1); instance = (plugin_instance *) gp_instance; if (instance->bypass_button) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(instance->bypass_button), !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON( instance->bypass_button))); } } } if (event->type == GDK_2BUTTON_PRESS && event->button == 1) { conf_clicked(NULL, NULL, NULL); } if (event->type == GDK_BUTTON_PRESS && event->button == 3 && gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(running_store), &iter, NULL, 0)) { gtk_menu_popup(GTK_MENU(rp_menu), NULL, NULL, NULL, NULL, event->button, event->time); return TRUE; } return FALSE; } gint refresh_on_list_changed_cb(gpointer data) { refresh_plugin_vect(0); return FALSE; } void running_list_row_inserted(GtkTreeModel * model, GtkTreePath * path, GtkTreeIter * iter) { if (added_plugin) { added_plugin = 0; return; } aqualung_timeout_add(100, refresh_on_list_changed_cb, NULL); } gint avail_key_pressed(GtkWidget * widget, GdkEventKey * event) { switch (event->keyval) { case GDK_a: case GDK_A: add_clicked(NULL, NULL, NULL); return TRUE; break; } return FALSE; } gint avail_dblclicked(GtkWidget * widget, GdkEventButton * event) { if (event->type == GDK_2BUTTON_PRESS && event->button == 1) { add_clicked(NULL, NULL, NULL); return TRUE; } return FALSE; } void set_all_plugins_status(gint status) { GtkTreeIter iter; gpointer gp_instance; plugin_instance * instance; int i = 0; if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(running_store), &iter)) { do { gtk_tree_model_get(GTK_TREE_MODEL(running_store), &iter, 1, &gp_instance, -1); instance = (plugin_instance *) gp_instance; if (instance->bypass_button) { if (status != -1) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(instance->bypass_button), status); else gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(instance->bypass_button), !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(instance->bypass_button))); } } while (i++, gtk_tree_model_iter_next(GTK_TREE_MODEL(running_store), &iter)); } } void rp__enable_all_cb(gpointer data) { set_all_plugins_status(FALSE); } void rp__disable_all_cb(gpointer data) { set_all_plugins_status(TRUE); } void rp__toggle_all_cb(gpointer data) { set_all_plugins_status(-1); } void rp__clear_list_cb(gpointer data) { GtkTreeIter iter; gpointer gp_instance; plugin_instance * instance; int i = 0; if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(running_store), &iter)) { do { gtk_tree_model_get(GTK_TREE_MODEL(running_store), &iter, 1, &gp_instance, -1); refresh_plugin_vect(-1); instance = (plugin_instance *) gp_instance; if (instance->handle) { if (instance->descriptor->deactivate) { instance->descriptor->deactivate(instance->handle); } instance->descriptor->cleanup(instance->handle); instance->handle = NULL; } if (instance->handle2) { if (instance->descriptor->deactivate) { instance->descriptor->deactivate(instance->handle2); } instance->descriptor->cleanup(instance->handle2); instance->handle2 = NULL; } if (instance->timeout) g_source_remove(instance->timeout); if (instance->window) gtk_widget_destroy(instance->window); trashlist_free(instance->trashlist); free(instance); } while (i++, gtk_tree_model_iter_next(GTK_TREE_MODEL(running_store), &iter)); gtk_list_store_clear(running_store); } set_active_state(); } void create_fxbuilder(void) { GtkWidget * hbox; GtkWidget * vbox; GtkWidget * frame_avail; GtkWidget * viewport_avail; GtkWidget * scrolled_win_avail; GtkWidget * frame_running; GtkWidget * viewport_running; GtkWidget * hbox_buttons; GtkWidget * rp__enable_all; GtkWidget * rp__disable_all; GtkWidget * rp__toggle_all; GtkWidget * rp__separator1; GtkWidget * rp__separator2; GtkWidget * rp__clear_list; GtkCellRenderer * renderer; GtkTreeViewColumn * column; /* window creating stuff */ fxbuilder_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(fxbuilder_window), _("LADSPA patch builder")); gtk_window_set_position(GTK_WINDOW(fxbuilder_window), GTK_WIN_POS_CENTER); g_signal_connect(G_OBJECT(fxbuilder_window), "delete_event", G_CALLBACK(fxbuilder_close), NULL); g_signal_connect(G_OBJECT(fxbuilder_window), "key_press_event", G_CALLBACK(fxbuilder_key_pressed), NULL); gtk_container_set_border_width(GTK_CONTAINER(fxbuilder_window), 2); hbox = gtk_hbox_new(FALSE, 0); gtk_container_add(GTK_CONTAINER(fxbuilder_window), hbox); frame_avail = gtk_frame_new(_("Available plugins")); gtk_box_pack_start(GTK_BOX(hbox), frame_avail, TRUE, TRUE, 5); vbox = gtk_vbox_new(FALSE, 0); gtk_container_set_border_width(GTK_CONTAINER(vbox), 3); gtk_container_add(GTK_CONTAINER(frame_avail), vbox); viewport_avail = gtk_viewport_new(NULL, NULL); gtk_box_pack_start(GTK_BOX(vbox), viewport_avail, TRUE, TRUE, 3); add_button = gtk_button_new_from_stock (GTK_STOCK_ADD); g_signal_connect(add_button, "clicked", G_CALLBACK(add_clicked), NULL); gtk_box_pack_start(GTK_BOX(vbox), add_button, FALSE, TRUE, 3); scrolled_win_avail = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_win_avail), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_container_add(GTK_CONTAINER(viewport_avail), scrolled_win_avail); /* create store of available plugins */ if (!avail_store) { avail_store = gtk_list_store_new(7, G_TYPE_STRING, /* 0: ID */ G_TYPE_STRING, /* 1: Name */ G_TYPE_STRING, /* 2: category */ G_TYPE_STRING, /* 3: n_ins */ G_TYPE_STRING, /* 4: n_outs */ G_TYPE_STRING, /* 5: filename */ G_TYPE_STRING); /* 6: index */ gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(avail_store), 1, GTK_SORT_ASCENDING); gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(avail_store), 0, compare_func, (gpointer) 0, NULL); gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(avail_store), 1, compare_func, (gpointer) 1, NULL); gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(avail_store), 2, compare_func, (gpointer) 2, NULL); gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(avail_store), 3, compare_func, (gpointer) 3, NULL); gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(avail_store), 4, compare_func, (gpointer) 4, NULL); /* fill avail_store with data */ parse_lrdf_data(); find_all_plugins(); } avail_list = gtk_tree_view_new_with_model(GTK_TREE_MODEL(avail_store)); gtk_tree_view_set_enable_search(GTK_TREE_VIEW(avail_list), FALSE); gtk_widget_set_size_request(avail_list, 400, 300); gtk_container_add(GTK_CONTAINER(scrolled_win_avail), avail_list); gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(avail_list), TRUE); g_signal_connect(G_OBJECT(avail_list), "key_press_event", G_CALLBACK(avail_key_pressed), NULL); g_signal_connect(G_OBJECT(avail_list), "button_press_event", G_CALLBACK(avail_dblclicked), NULL); avail_select = gtk_tree_view_get_selection(GTK_TREE_VIEW(avail_list)); gtk_tree_selection_set_mode(avail_select, GTK_SELECTION_MULTIPLE); renderer = gtk_cell_renderer_text_new(); g_object_set(G_OBJECT(renderer), "ellipsize", PANGO_ELLIPSIZE_END, NULL); column = gtk_tree_view_column_new_with_attributes(_("ID"), renderer, "text", 0, NULL); gtk_tree_view_column_set_resizable(GTK_TREE_VIEW_COLUMN(column), TRUE); gtk_tree_view_append_column(GTK_TREE_VIEW(avail_list), column); gtk_tree_view_column_set_sort_column_id(GTK_TREE_VIEW_COLUMN(column), 0); if (options.simple_view_in_fx) gtk_tree_view_column_set_visible(GTK_TREE_VIEW_COLUMN (column), FALSE); column = gtk_tree_view_column_new_with_attributes(_("Name"), renderer, "text", 1, NULL); gtk_tree_view_column_set_resizable(GTK_TREE_VIEW_COLUMN(column), TRUE); gtk_tree_view_append_column(GTK_TREE_VIEW(avail_list), column); gtk_tree_view_column_set_sort_column_id(GTK_TREE_VIEW_COLUMN(column), 1); column = gtk_tree_view_column_new_with_attributes(_("Category"), renderer, "text", 2, NULL); gtk_tree_view_column_set_resizable(GTK_TREE_VIEW_COLUMN(column), TRUE); gtk_tree_view_append_column(GTK_TREE_VIEW(avail_list), column); gtk_tree_view_column_set_sort_column_id(GTK_TREE_VIEW_COLUMN(column), 2); if (options.simple_view_in_fx) gtk_tree_view_column_set_visible(GTK_TREE_VIEW_COLUMN (column), FALSE); column = gtk_tree_view_column_new_with_attributes(_("Inputs"), renderer, "text", 3, NULL); gtk_tree_view_column_set_resizable(GTK_TREE_VIEW_COLUMN(column), TRUE); gtk_tree_view_append_column(GTK_TREE_VIEW(avail_list), column); gtk_tree_view_column_set_sort_column_id(GTK_TREE_VIEW_COLUMN(column), 3); if (options.simple_view_in_fx) gtk_tree_view_column_set_visible(GTK_TREE_VIEW_COLUMN (column), FALSE); column = gtk_tree_view_column_new_with_attributes(_("Outputs"), renderer, "text", 4, NULL); gtk_tree_view_column_set_resizable(GTK_TREE_VIEW_COLUMN(column), TRUE); gtk_tree_view_append_column(GTK_TREE_VIEW(avail_list), column); gtk_tree_view_column_set_sort_column_id(GTK_TREE_VIEW_COLUMN(column), 4); if (options.simple_view_in_fx) gtk_tree_view_column_set_visible(GTK_TREE_VIEW_COLUMN (column), FALSE); frame_running = gtk_frame_new(_("Running plugins")); gtk_box_pack_start(GTK_BOX(hbox), frame_running, TRUE, TRUE, 5); vbox = gtk_vbox_new(FALSE, 0); gtk_container_set_border_width(GTK_CONTAINER(vbox), 3); gtk_container_add(GTK_CONTAINER(frame_running), vbox); viewport_running = gtk_viewport_new(NULL, NULL); gtk_box_pack_start(GTK_BOX(vbox), viewport_running, TRUE, TRUE, 3); hbox_buttons = gtk_hbox_new(TRUE, 0); gtk_box_pack_start(GTK_BOX(vbox), hbox_buttons, FALSE, TRUE, 3); remove_button = gtk_button_new_from_stock (GTK_STOCK_REMOVE); g_signal_connect(remove_button, "clicked", G_CALLBACK(remove_clicked), NULL); gtk_box_pack_start(GTK_BOX(hbox_buttons), remove_button, TRUE, TRUE, 0); conf_button = gui_stock_label_button(_("_Configure"), GTK_STOCK_PREFERENCES); g_signal_connect(conf_button, "clicked", G_CALLBACK(conf_clicked), NULL); gtk_box_pack_start(GTK_BOX(hbox_buttons), conf_button, TRUE, TRUE, 0); scrolled_win_running = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_win_running), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_container_add(GTK_CONTAINER(viewport_running), scrolled_win_running); /* create store of running plugins */ if (!running_store) { running_store = gtk_list_store_new(2, G_TYPE_STRING, /* Name */ G_TYPE_POINTER); /* instance */ g_signal_connect(G_OBJECT(running_store), "row_inserted", G_CALLBACK(running_list_row_inserted), NULL); } running_list = gtk_tree_view_new_with_model(GTK_TREE_MODEL(running_store)); gtk_widget_set_size_request(running_list, 200, 300); gtk_container_add(GTK_CONTAINER(scrolled_win_running), running_list); gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(running_list), TRUE); gtk_tree_view_set_reorderable(GTK_TREE_VIEW(running_list), TRUE); g_signal_connect(G_OBJECT(running_list), "key_press_event", G_CALLBACK(running_list_key_pressed), NULL); g_signal_connect(G_OBJECT(running_list), "button_press_event", G_CALLBACK(running_list_button_pressed), NULL); running_select = gtk_tree_view_get_selection(GTK_TREE_VIEW(running_list)); gtk_tree_selection_set_mode(running_select, GTK_SELECTION_SINGLE); renderer = gtk_cell_renderer_text_new(); g_object_set(G_OBJECT(renderer), "ellipsize", PANGO_ELLIPSIZE_END, NULL); column = gtk_tree_view_column_new_with_attributes(_("Name"), renderer, "text", 0, NULL); gtk_tree_view_column_set_resizable(GTK_TREE_VIEW_COLUMN(column), TRUE); gtk_tree_view_append_column(GTK_TREE_VIEW(running_list), column); /* running plugins menu */ rp_menu = gtk_menu_new(); rp__enable_all = gtk_menu_item_new_with_label(_("Enable all plugins")); rp__disable_all = gtk_menu_item_new_with_label(_("Disable all plugins")); rp__separator1 = gtk_separator_menu_item_new(); rp__toggle_all = gtk_menu_item_new_with_label(_("Invert current state")); rp__separator2 = gtk_separator_menu_item_new(); rp__clear_list = gtk_menu_item_new_with_label(_("Clear list")); gtk_menu_shell_append(GTK_MENU_SHELL(rp_menu), rp__enable_all); gtk_menu_shell_append(GTK_MENU_SHELL(rp_menu), rp__disable_all); gtk_menu_shell_append(GTK_MENU_SHELL(rp_menu), rp__separator1); gtk_menu_shell_append(GTK_MENU_SHELL(rp_menu), rp__toggle_all); gtk_menu_shell_append(GTK_MENU_SHELL(rp_menu), rp__separator2); gtk_menu_shell_append(GTK_MENU_SHELL(rp_menu), rp__clear_list); g_signal_connect_swapped(G_OBJECT(rp__enable_all), "activate", G_CALLBACK(rp__enable_all_cb), NULL); g_signal_connect_swapped(G_OBJECT(rp__disable_all), "activate", G_CALLBACK(rp__disable_all_cb), NULL); g_signal_connect_swapped(G_OBJECT(rp__toggle_all), "activate", G_CALLBACK(rp__toggle_all_cb), NULL); g_signal_connect_swapped(G_OBJECT(rp__clear_list), "activate", G_CALLBACK(rp__clear_list_cb), NULL); gtk_widget_show(rp__enable_all); gtk_widget_show(rp__disable_all); gtk_widget_show(rp__separator1); gtk_widget_show(rp__toggle_all); gtk_widget_show(rp__separator2); gtk_widget_show(rp__clear_list); } void save_plugin_data(void) { int i = 0; int k; GtkTreeIter iter; gpointer gp_instance; plugin_instance * instance; xmlDocPtr doc; xmlNodePtr root; xmlNodePtr plugin_node; xmlNodePtr port_node; int c, d; FILE * fin; FILE * fout; char tmpname[MAXLEN]; char plugin_file[MAXLEN]; char str[32]; sprintf(plugin_file, "%s/plugin.xml", options.confdir); doc = xmlNewDoc((const xmlChar*) "1.0"); root = xmlNewNode(NULL, (const xmlChar*) "aqualung_plugin"); xmlDocSetRootElement(doc, root); while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(running_store), &iter, NULL, i)) { gtk_tree_model_get(GTK_TREE_MODEL(running_store), &iter, 1, &gp_instance, -1); instance = (plugin_instance *) gp_instance; plugin_node = xmlNewTextChild(root, NULL, (const xmlChar*) "plugin", NULL); xmlNewTextChild(plugin_node, NULL, (const xmlChar*) "filename", (xmlChar*) instance->filename); snprintf(str, 31, "%d", instance->index); xmlNewTextChild(plugin_node, NULL, (const xmlChar*) "index", (xmlChar*) str); snprintf(str, 31, "%d", instance->is_bypassed); xmlNewTextChild(plugin_node, NULL, (const xmlChar*) "is_bypassed", (xmlChar*) str); for (k = 0; k < MAX_KNOBS && k < instance->descriptor->PortCount; ++k) { if (!LADSPA_IS_PORT_CONTROL(instance->descriptor->PortDescriptors[k])) continue; if (LADSPA_IS_PORT_OUTPUT(instance->descriptor->PortDescriptors[k])) continue; port_node = xmlNewTextChild(plugin_node, NULL, (const xmlChar*) "port", NULL); snprintf(str, 31, "%d", k); xmlNewTextChild(port_node, NULL, (const xmlChar*) "index", (xmlChar*) str); snprintf(str, 31, "%f", instance->knobs[k]); xmlNewTextChild(port_node, NULL, (const xmlChar*) "value", (xmlChar*) str); } ++i; } sprintf(tmpname, "%s/plugin.xml.temp", options.confdir); xmlSaveFormatFile(tmpname, doc, 1); xmlFreeDoc(doc); if ((fin = fopen(plugin_file, "rt")) == NULL) { fprintf(stderr, "Error opening file: %s\n", plugin_file); return; } if ((fout = fopen(tmpname, "rt")) == NULL) { fprintf(stderr, "Error opening file: %s\n", tmpname); return; } c = 0; d = 0; while (((c = fgetc(fin)) != EOF) && ((d = fgetc(fout)) != EOF)) { if (c != d) { fclose(fin); fclose(fout); unlink(plugin_file); rename(tmpname, plugin_file); return; } } fclose(fin); fclose(fout); unlink(tmpname); } void parse_plugin(xmlDocPtr doc, xmlNodePtr cur) { xmlChar * key; int k; char filename[MAXLEN]; int index = -1; int is_bypassed; GtkTreeIter running_iter; plugin_instance * instance = NULL; char bypassed_name[MAXLEN]; LADSPA_Data knobs[MAX_KNOBS]; filename[0] = '\0'; cur = cur->xmlChildrenNode; while (cur != NULL) { if ((!xmlStrcmp(cur->name, (const xmlChar *)"filename"))) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); if (key != NULL) strncpy(filename, (char *) key, MAXLEN-1); xmlFree(key); if (filename[0] == '\0') { fprintf(stderr, "Error in XML aqualung_plugin: " "plugin is required, but NULL\n"); } } else if ((!xmlStrcmp(cur->name, (const xmlChar *)"index"))) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); if (key != NULL) sscanf((char *) key, "%d", &index); xmlFree(key); } else if ((!xmlStrcmp(cur->name, (const xmlChar *)"is_bypassed"))) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); if (key != NULL) sscanf((char *) key, "%d", &is_bypassed); xmlFree(key); } else if ((!xmlStrcmp(cur->name, (const xmlChar *)"port"))) { int port_index = -1; float port_value = 0.0f; xmlNodePtr port_node = cur->xmlChildrenNode; while (port_node != NULL) { if ((!xmlStrcmp(port_node->name, (const xmlChar *)"index"))) { key = xmlNodeListGetString(doc, port_node->xmlChildrenNode, 1); if (key != NULL) sscanf((char *) key, "%d", &port_index); xmlFree(key); } else if ((!xmlStrcmp(port_node->name, (const xmlChar *)"value"))) { key = xmlNodeListGetString(doc, port_node->xmlChildrenNode, 1); if (key != NULL) sscanf((char *) key, "%f", &port_value); xmlFree(key); } port_node = port_node->next; } if ((port_index >= 0) && (port_index < MAX_KNOBS)) { knobs[port_index] = port_value; } } cur = cur->next; } if ((filename[0] != '\0') && (index >= 0)) { /* create plugin, restore settings */ if (n_plugins >= MAX_PLUGINS) { fprintf(stderr, "Maximum number of running plugin instances (%d) reached; " "cannot add more.\n", MAX_PLUGINS); return; } instance = instantiate(filename, index); if (instance) { connect_port(instance); activate(instance); for (k = 0; k < MAX_KNOBS && k < instance->descriptor->PortCount; ++k) { if (!LADSPA_IS_PORT_CONTROL(instance->descriptor->PortDescriptors[k])) continue; if (LADSPA_IS_PORT_OUTPUT(instance->descriptor->PortDescriptors[k])) continue; instance->knobs[k] = knobs[k]; } instance->is_restored = 1; instance->is_bypassed = is_bypassed; build_plugin_window(instance); get_bypassed_name(instance, bypassed_name); added_plugin = 1; /* so resort handler will not do any harm */ gtk_list_store_append(running_store, &running_iter); gtk_list_store_set(running_store, &running_iter, 0, bypassed_name, 1, (gpointer)instance, -1); refresh_plugin_vect(1); } } return; } void load_plugin_data(void) { xmlDocPtr doc; xmlNodePtr cur; xmlNodePtr root; char plugin_file[MAXLEN]; FILE * f; sprintf(plugin_file, "%s/plugin.xml", options.confdir); if ((f = fopen(plugin_file, "rt")) == NULL) { fprintf(stderr, "No plugin.xml -- creating empty one: %s\n", plugin_file); doc = xmlNewDoc((const xmlChar*) "1.0"); root = xmlNewNode(NULL, (const xmlChar*) "aqualung_plugin"); xmlDocSetRootElement(doc, root); xmlSaveFormatFile(plugin_file, doc, 1); xmlFreeDoc(doc); return; } fclose(f); doc = xmlParseFile(plugin_file); if (doc == NULL) { fprintf(stderr, "An XML error occured while parsing %s\n", plugin_file); return; } cur = xmlDocGetRootElement(doc); if (cur == NULL) { fprintf(stderr, "load_config: empty XML document\n"); xmlFreeDoc(doc); return; } if (xmlStrcmp(cur->name, (const xmlChar *)"aqualung_plugin")) { fprintf(stderr, "load_config: XML document of the wrong type, " "root node != aqualung_plugin\n"); xmlFreeDoc(doc); return; } cur = cur->xmlChildrenNode; while (cur != NULL) { if ((!xmlStrcmp(cur->name, (const xmlChar *)"plugin"))) { parse_plugin(doc, cur); } cur = cur->next; } xmlFreeDoc(doc); return; } #else #include int fxbuilder_on = 0; GtkWidget * fxbuilder_window = NULL; #endif /* HAVE_LADSPA */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/podcast.h0000644000175000001440000000404111002132477013503 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: podcast.h 1013 2008-03-10 21:02:23Z peterszilagyi $ */ #ifndef _PODCAST_H #define _PODCAST_H #include #ifdef HAVE_PODCAST #include typedef struct { char * file; char * title; char * desc; char * url; int new; float duration; /* sec */ unsigned size; /* byte */ unsigned date; /* sec */ } podcast_item_t; enum { PODCAST_AUTO_CHECK = (1 << 0), PODCAST_COUNT_LIMIT = (1 << 1), PODCAST_SIZE_LIMIT = (1 << 2), PODCAST_DATE_LIMIT = (1 << 3) }; enum { PODCAST_STATE_IDLE = 0, PODCAST_STATE_PENDING, PODCAST_STATE_UPDATE, PODCAST_STATE_ABORTED }; typedef struct { char * dir; char * title; char * author; char * desc; char * url; unsigned check_interval; /* sec */ unsigned last_checked; /* sec */ /* limits: zero means no limit */ unsigned count_limit; unsigned size_limit; /* MB */ unsigned date_limit; /* sec */ int flags; int state; GSList * items; } podcast_t; podcast_t * podcast_new(void); void podcast_get_display_name(podcast_t * podcast, char * buf); podcast_item_t * podcast_item_new(void); void podcast_free(podcast_t * podcast); void podcast_item_free(podcast_item_t * item); void podcast_update(podcast_t * podcast); #endif /* HAVE_PODCAST */ #endif /* _PODCAST_H */ aqualung-0.9beta11/src/podcast.c0000644000175000001440000004572611002132477013515 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: podcast.c 1013 2008-03-10 21:02:23Z peterszilagyi $ */ #include #ifdef HAVE_PODCAST #include #include #include #include #include #include #include #include #ifdef _WIN32 #include #else #include #endif /* _WIN32*/ #include "common.h" #include "i18n.h" #include "utils.h" #include "decoder/file_decoder.h" #include "options.h" #include "httpc.h" #include "store_podcast.h" #include "podcast.h" #define BUFSIZE 10240 extern options_t options; podcast_t * podcast_new(void) { podcast_t * podcast; if ((podcast = (podcast_t *)calloc(1, sizeof(podcast_t))) == NULL) { fprintf(stderr, "podcast_new: calloc error\n"); return NULL; } podcast->state = PODCAST_STATE_IDLE; podcast->items = NULL; return podcast; } void podcast_get_display_name(podcast_t * podcast, char * buf) { if (podcast->author != NULL && podcast->title != NULL) { snprintf(buf, MAXLEN-1, "%s: %s", podcast->author, podcast->title); } else if (podcast->title != NULL) { strncpy(buf, podcast->title, MAXLEN-1); } else { strncpy(buf, _("Untitled"), MAXLEN-1); } } void podcast_free(podcast_t * podcast) { if (podcast->dir) { free(podcast->dir); } if (podcast->title) { free(podcast->title); } if (podcast->author) { free(podcast->author); } if (podcast->desc) { free(podcast->desc); } if (podcast->url) { free(podcast->url); } g_slist_free(podcast->items); free(podcast); } podcast_item_t * podcast_item_new(void) { podcast_item_t * item; if ((item = (podcast_item_t *)calloc(1, sizeof(podcast_item_t))) == NULL) { fprintf(stderr, "podcast_item_new: calloc error\n"); return NULL; } item->new = 1; item->size = 0; item->date = 0; item->duration = 0.0f; return item; } void podcast_item_free(podcast_item_t * item) { if (item->file) { free(item->file); } if (item->title) { free(item->title); } if (item->desc) { free(item->desc); } if (item->url) { free(item->url); } free(item); } gint podcast_item_compare_date(gconstpointer list1, gconstpointer list2) { unsigned date1 = ((podcast_item_t *)list1)->date; unsigned date2 = ((podcast_item_t *)list2)->date; if (date1 < date2) { return 1; } else if (date1 > date2) { return -1; } return 0; } gint podcast_item_compare_url(gconstpointer list, gconstpointer url) { return strcmp(((podcast_item_t *)list)->url, (char * )url); } char * podcast_file_from_url(char * url) { char * str; char * valid = "abcdefghijklmnopqrstuvwxyz0123456789"; char * lastdot; char * file; str = g_ascii_strdown(url, -1); lastdot = strrchr(str, '.'); g_strcanon(str, valid, '_'); if (lastdot != NULL) { *lastdot = '.'; } if (strstr(str, "http___") != NULL) { file = strdup(str + 7); } else { file = strdup(str); } g_free(str); return file; } unsigned parse_rfc822(char * str) { char * months[] = { "Ja", "F", "Mar", "Ap", "May", "Jun", "Jul", "Au", "S", "O", "N", "D" }; char * tz[] = { "UT", "GMT", "EST", "EDT", "CST", "CDT", "MST", "MDT", "PST", "PDT", "A", "B", "C", "D", "E", "F", "G", "H", "I", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" }; int tzval[] = { 0, 0, -5, -4, -6, -5, -7, -6, -8, -7, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0 }; int i; int y = 0; /* year */ int m = 0; /* month */ int d = 0; /* day */ int H = 0; /* hour */ int M = 0; /* min */ int S = 0; /* sec */ char b[16]; /* month name */ char z[16]; /* timezone */ if (sscanf(str, "%*[^,], %d %15s %d %d:%d:%d %15s", &d, b, &y, &H, &M, &S, z) == 7) { GDate * epoch; GDate * date; for (i = 0; i < 12; i++) { if (strstr(b, months[i]) != NULL) { m = i + 1; break; } } if (y < 100) { y += 2000; } else if (y < 1000) { y += 1900; } if (!g_date_valid_dmy(d, m, y)) { return 0; } for (i = 0; i < sizeof(tzval) / sizeof(int); i++) { if (!strcmp(tz[i], z)) { H += tzval[i]; break; } } if (sscanf(z, "%d", &i) == 1) { H -= i / 100; M -= i % 100; } epoch = g_date_new_dmy(1, 1, 1970); date = g_date_new_dmy(d, m, y); return g_date_days_between(epoch, date) * 86400 + H * 3600 + M * 60 + S; } return 0; } unsigned parse_ymd(char * str) { int a = 0; int b = 0; int c = 0; if (sscanf(str, "%d-%d-%d", &a, &b, &c) == 3) { GDate * epoch; GDate * date; int y = 0, m = 0, d = 0; if (a > 1900) { y = a; m = b; d = c; } else if (c > 1900) { y = c; m = a; d = b; } else { return 0; } if (!g_date_valid_dmy(d, m, y)) { return 0; } epoch = g_date_new_dmy(1, 1, 1970); date = g_date_new_dmy(d, m, y); return g_date_days_between(epoch, date) * 86400; } return 0; } unsigned parse_rss_date(char * str) { GTimeVal tval; unsigned val; if ((val = parse_rfc822(str)) > 0) { return val; } if ((val = parse_ymd(str)) > 0) { return val; } g_get_current_time(&tval); return tval.tv_sec; } unsigned parse_atom_date(char * str) { GTimeVal tval; #if GLIB_CHECK_VERSION(2,12,0) if (!g_time_val_from_iso8601(str, &tval)) #endif /* GLIB_CHECK_VERSION */ { g_get_current_time(&tval); } return tval.tv_sec; } int podcast_generic_download(podcast_t * podcast, char * url, char * path, void (* callback)(podcast_download_t *), podcast_download_t * pd) { http_session_t * session; char buf[BUFSIZE]; FILE * out; long long pos = 0; int n_read; int ret; int credit = 5; int penalty = 0; int content_length = 0; int percent = 0; int _percent = 0; if ((out = fopen(path, "wb")) == NULL) { fprintf(stderr, "podcast_generic_download: unable to open file %s\n", path); return -1; } while (credit > 0) { if (podcast->state == PODCAST_STATE_ABORTED) { break; } if ((session = httpc_new()) == NULL) { fclose(out); unlink(path); return -1; } if ((ret = httpc_init(session, NULL, url, options.inet_use_proxy, options.inet_proxy, options.inet_proxy_port, options.inet_noproxy_domains, 0L)) != HTTPC_OK) { fprintf(stderr, "podcast_generic_download: httpc_init failed, ret = %d\n", ret); httpc_del(session); --credit; continue; } content_length = session->headers.content_length; if (httpc_seek(session, pos, SEEK_SET) < -1) { fprintf(stderr, "httpc_seek failed\n"); --credit; continue; } penalty = 1; while ((n_read = httpc_read(session, buf, BUFSIZE)) > 0) { if (podcast->state == PODCAST_STATE_ABORTED) { break; } pos += n_read; penalty = 0; fwrite(buf, sizeof(char), n_read, out); if (callback != NULL && content_length > 0) { _percent = (int)((100.0 * pos) / content_length); if (_percent > percent) { pd->percent = percent = _percent; callback(pd); } } } httpc_close(session); httpc_del(session); if (podcast->state == PODCAST_STATE_ABORTED) { break; } if (n_read < 0) { credit -= penalty; continue; } break; } if (podcast->state == PODCAST_STATE_ABORTED || credit == 0) { fclose(out); unlink(path); return -1; } fclose(out); return 0; } void string_remove_html(char * str) { int i, j; if (str == NULL) { return; } for (i = j = 0; str[i]; i++) { if (str[i] == '<') { while (str[i] && str[i] != '>') { ++i; } if (str[i] == '\0') { break; } } else { str[j++] = str[i]; } } str[j] = '\0'; } void parse_rss_item(podcast_t * podcast, GSList ** list, xmlDocPtr doc, xmlNodePtr item) { podcast_item_t * pitem; xmlNodePtr node; if ((pitem = podcast_item_new()) == NULL) { return; } for (node = item->xmlChildrenNode; node != NULL; node = node->next) { if (!xmlStrcmp(node->name, (const xmlChar *)"title")) { pitem->title = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1); } else if (!xmlStrcmp(node->name, (const xmlChar *)"description")) { pitem->desc = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1); } else if (!xmlStrcmp(node->name, (const xmlChar *)"summary")) { if (pitem->desc == NULL) { pitem->desc = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1); } } else if (!xmlStrcmp(node->name, (const xmlChar *)"enclosure")) { xmlChar * len; if ((len = xmlGetProp(node, (const xmlChar *)"length")) != NULL) { sscanf((char *)len, "%u", &pitem->size); xmlFree(len); } pitem->url = (char *)xmlGetProp(node, (const xmlChar *)"url"); } else if (!xmlStrcmp(node->name, (const xmlChar *)"pubDate")) { xmlChar * tmp = xmlNodeListGetString(doc, node->xmlChildrenNode, 1); pitem->date = parse_rss_date((char *)tmp); xmlFree(tmp); } } if (pitem->url == NULL) { podcast_item_free(pitem); return; } string_remove_html(pitem->desc); if (pitem->title == NULL) { pitem->title = strdup(_("Untitled")); } if (g_slist_find_custom(*list, pitem->url, podcast_item_compare_url) == NULL) { *list = g_slist_prepend(*list, pitem); } else { podcast_item_free(pitem); } } void parse_rss(podcast_t * podcast, GSList ** list, xmlDocPtr doc, xmlNodePtr rss) { xmlNodePtr channel; xmlNodePtr node; for (channel = rss->xmlChildrenNode; channel != NULL; channel = channel->next) { if (!xmlStrcmp(channel->name, (const xmlChar *)"channel")) { break; } } if (channel == NULL) { fprintf(stderr, "parse_rss: no channel found\n"); return; } for (node = channel->xmlChildrenNode; node != NULL; node = node->next) { if (!xmlStrcmp(node->name, (const xmlChar *)"title")) { if (podcast->title) { free(podcast->title); } podcast->title = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1); } else if (!xmlStrcmp(node->name, (const xmlChar *)"author")) { if (podcast->author) { free(podcast->author); } podcast->author = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1); } else if (!xmlStrcmp(node->name, (const xmlChar *)"description")) { if (podcast->desc) { free(podcast->desc); } podcast->desc = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1); } else if (!xmlStrcmp(node->name, (const xmlChar *)"summary")) { if (podcast->desc == NULL) { podcast->desc = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1); } } } if (podcast->title == NULL) { podcast->title = strdup(_("Untitled")); } string_remove_html(podcast->desc); for (node = channel->xmlChildrenNode; node != NULL; node = node->next) { if (!xmlStrcmp(node->name, (const xmlChar *)"item")) { parse_rss_item(podcast, list, doc, node); } } } void parse_atom_item(podcast_t * podcast, GSList ** list, xmlDocPtr doc, xmlNodePtr entry) { podcast_item_t * pitem; xmlNodePtr node; if ((pitem = podcast_item_new()) == NULL) { return; } for (node = entry->xmlChildrenNode; node != NULL; node = node->next) { if (!xmlStrcmp(node->name, (const xmlChar *)"title")) { pitem->title = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1); } else if (!xmlStrcmp(node->name, (const xmlChar *)"summary")) { if (pitem->desc) { free(pitem->desc); } pitem->desc = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1); } else if (pitem->url == NULL && !xmlStrcmp(node->name, (const xmlChar *)"link")) { xmlChar * rel = NULL; if ((rel = xmlGetProp(node, (const xmlChar *)"rel")) != NULL && !xmlStrcmp(rel, (const xmlChar *)"enclosure")) { xmlChar * len; if ((len = xmlGetProp(node, (const xmlChar *)"length")) != NULL) { sscanf((char *)len, "%u", &pitem->size); xmlFree(len); } pitem->url = (char *)xmlGetProp(node, (const xmlChar *)"href"); } if (rel != NULL) { xmlFree(rel); } } else if (!xmlStrcmp(node->name, (const xmlChar *)"updated") || /* Atom 1.0 */ !xmlStrcmp(node->name, (const xmlChar *)"modified")) { /* Atom 0.3 */ xmlChar * tmp = xmlNodeListGetString(doc, node->xmlChildrenNode, 1); pitem->date = parse_atom_date((char *)tmp); xmlFree(tmp); } } if (pitem->url == NULL) { podcast_item_free(pitem); return; } string_remove_html(pitem->desc); if (pitem->title == NULL) { pitem->title = strdup(_("Untitled")); } if (g_slist_find_custom(*list, pitem->url, podcast_item_compare_url) == NULL) { *list = g_slist_prepend(*list, pitem); } else { podcast_item_free(pitem); } } void parse_atom(podcast_t * podcast, GSList ** list, xmlDocPtr doc, xmlNodePtr feed) { xmlNodePtr node; for (node = feed->xmlChildrenNode; node != NULL; node = node->next) { if (!xmlStrcmp(node->name, (const xmlChar *)"title")) { if (podcast->title) { free(podcast->title); } podcast->title = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1); } else if (!xmlStrcmp(node->name, (const xmlChar *)"author")) { xmlNodePtr n; for (n = node->xmlChildrenNode; n; n = n->next) { if (!xmlStrcmp(n->name, (const xmlChar *)"name")) { if (podcast->author) { free(podcast->author); } podcast->author = (char *)xmlNodeListGetString(doc, n->xmlChildrenNode, 1); break; } } } else if (!xmlStrcmp(node->name, (const xmlChar *)"subtitle") || /* Atom 1.0 */ !xmlStrcmp(node->name, (const xmlChar *)"tagline")) { /* Atom 0.3 */ if (podcast->desc) { free(podcast->desc); } podcast->desc = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1); } } if (podcast->title == NULL) { podcast->title = strdup(_("Untitled")); } string_remove_html(podcast->desc); for (node = feed->xmlChildrenNode; node != NULL; node = node->next) { if (!xmlStrcmp(node->name, (const xmlChar *)"entry")) { parse_atom_item(podcast, list, doc, node); } } } int podcast_parse(podcast_t * podcast, GSList ** list) { xmlDocPtr doc; xmlNodePtr node; char filename[MAXLEN]; char * file; file = podcast_file_from_url(podcast->url); snprintf(filename, MAXLEN-1, "%s/.%s", podcast->dir, file); free(file); if (podcast_generic_download(podcast, podcast->url, filename, NULL, NULL) < 0) { return -1; } doc = xmlParseFile(filename); if (doc == NULL) { unlink(filename); return -1; } node = xmlDocGetRootElement(doc); if (node == NULL) { xmlFreeDoc(doc); unlink(filename); return -1; } if (!xmlStrcmp(node->name, (const xmlChar *)"rss")) { parse_rss(podcast, list, doc, node); } else if (!xmlStrcmp(node->name, (const xmlChar *)"feed")) { parse_atom(podcast, list, doc, node); } else { fprintf(stderr, "unknown feed format: %s\n", node->name); } xmlFreeDoc(doc); unlink(filename); return 0; } GSList * podcast_list_remove_item(podcast_t * podcast, GSList * list, GSList * litem) { podcast_item_t * item = (podcast_item_t *)litem->data; if (item->file) { if (unlink(item->file) < 0) { fprintf(stderr, "unlink: unable to unlink %s\n", item->file); perror("unlink"); } podcast->items = g_slist_remove(podcast->items, item); store_podcast_remove_item(podcast, item); } else { podcast_item_free(item); } return g_slist_delete_link(list, litem); } void podcast_item_download(podcast_download_t * pd, GSList ** list, GSList * node) { podcast_item_t * item = (podcast_item_t *)node->data; char * file; char path[MAXLEN]; float duration; struct stat statbuf; file = podcast_file_from_url(item->url); snprintf(path, MAXLEN-1, "%s/%s", pd->podcast->dir, file); free(file); pd->ncurrent++; pd->percent = 0; store_podcast_update_podcast_download(pd); if (podcast_generic_download(pd->podcast, item->url, path, store_podcast_update_podcast_download, pd) < 0) { goto failed; } if (stat(path, &statbuf) < 0) { goto failed; } if ((duration = get_file_duration(path)) < 0.0f) { goto failed; } item->duration = duration; item->size = statbuf.st_size; item->file = strdup(path); pd->podcast->items = g_slist_prepend(pd->podcast->items, item); store_podcast_add_item(pd->podcast, item); return; failed: *list = podcast_list_remove_item(pd->podcast, *list, node); } void podcast_apply_limits(podcast_t * podcast, GSList ** list) { GSList * node; unsigned size = 0; int count = 0; for (node = *list; node; node = node->next) { podcast_item_t * item = (podcast_item_t *)node->data; size += item->size; ++count; } node = g_slist_last(*list); while (*list != NULL && ((podcast->flags & PODCAST_DATE_LIMIT && podcast->last_checked - ((podcast_item_t *)node->data)->date > podcast->date_limit) || (podcast->flags & PODCAST_SIZE_LIMIT && size > podcast->size_limit) || (podcast->flags & PODCAST_COUNT_LIMIT && count > podcast->count_limit))) { size -= ((podcast_item_t *)node->data)->size; --count; *list = podcast_list_remove_item(podcast, *list, node); node = g_slist_last(*list); } } int podcast_download_next(podcast_download_t * pd, GSList ** list) { GSList * node; for (node = *list; node; node = node->next) { podcast_item_t * item = (podcast_item_t *)node->data; if (pd->podcast->state == PODCAST_STATE_ABORTED) { if (item->file == NULL) { podcast_item_free(item); } continue; } if (item->file == NULL) { podcast_item_download(pd, list, node); return 1; } } return 0; } void * podcast_update_thread(void * arg) { podcast_t * podcast = (podcast_t *)arg; podcast_download_t * pd; GSList * node; GTimeVal tval; GSList * list; AQUALUNG_THREAD_DETACH(); if ((pd = podcast_download_new(podcast)) == NULL) { return NULL; } list = g_slist_copy(podcast->items); if (podcast_parse(podcast, &list) < 0) { goto finish; } list = g_slist_sort(list, podcast_item_compare_date); g_get_current_time(&tval); podcast->last_checked = tval.tv_sec; podcast_apply_limits(podcast, &list); for (node = list; node; node = node->next) { if (((podcast_item_t *)node->data)->file == NULL) { pd->ndownloads++; } } while (podcast_download_next(pd, &list)) { podcast_apply_limits(podcast, &list); } finish: g_slist_free(list); store_podcast_update_podcast(pd); return NULL; } void podcast_update(podcast_t * podcast) { if (podcast->state == PODCAST_STATE_IDLE || podcast->state == PODCAST_STATE_PENDING) { AQUALUNG_THREAD_DECLARE(thread_id); podcast->state = PODCAST_STATE_UPDATE; AQUALUNG_THREAD_CREATE(thread_id, NULL, podcast_update_thread, podcast); } } #endif /* HAVE_PODCAST */ aqualung-0.9beta11/src/ports.h0000644000175000001440000000221510612341733013221 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: ports.h 524 2007-01-06 15:39:18Z pasp $ */ #ifndef _ports_h #define _ports_h #include #ifdef HAVE_JACK #define MAX_JACK_CLIENTS 128 void port_setup_dialog(void); void ports_clicked_close(GtkWidget * widget, gpointer * data); #endif /* HAVE_JACK */ #endif /* _ports_h */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/ports.c0000644000175000001440000004145010736426776013242 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: ports.c 973 2008-01-01 11:16:27Z peterszilagyi $ */ #include #ifdef HAVE_JACK #include #include #include #include #include #include #include #include #include "common.h" #include "utils_gui.h" #include "i18n.h" #include "ports.h" #define LIST_WIDTH 200 #define LIST_HEIGHT 100 extern GtkWidget * main_window; /* JACK data */ extern jack_port_t * out_L_port; extern jack_port_t * out_R_port; extern jack_client_t * jack_client; GtkWidget * ports_window = NULL; GtkWidget * nb_outs; GtkWidget * nb_out_labels[MAX_JACK_CLIENTS]; GtkWidget * vbox_dl; /* down-left */ GtkWidget * vbox_dr; /* down-right */ GtkWidget * tree_out_L; GtkWidget * tree_out_R; GtkListStore * store_out_L; GtkListStore * store_out_R; GtkTreeViewColumn * column_out_L; GtkTreeViewColumn * column_out_R; int n_clients; GtkListStore * store_out_nb[MAX_JACK_CLIENTS]; gint timeout_tag; int out_selector = 0; void scan_connections(jack_port_t * port, GtkListStore * store); void setup_notebook_out(void); gint ports_timeout_callback(gpointer data) { switch((int)data) { case 1: gtk_list_store_clear(store_out_L); scan_connections(out_L_port, store_out_L); break; case 2: gtk_list_store_clear(store_out_R); scan_connections(out_R_port, store_out_R); break; } return 0; } int port_window_close(GtkWidget *widget, gpointer * data) { ports_window = NULL; return 0; } void clicked_rescan(GtkWidget * widget, gpointer * data) { gtk_list_store_clear(store_out_L); scan_connections(out_L_port, store_out_L); gtk_list_store_clear(store_out_R); scan_connections(out_R_port, store_out_R); /* re-build notebook */ gtk_widget_destroy(nb_outs); n_clients = 0; nb_outs = gtk_notebook_new(); gtk_box_pack_start(GTK_BOX(vbox_dr), nb_outs, TRUE, TRUE, 2); setup_notebook_out(); gtk_widget_show(nb_outs); } void ports_clicked_close(GtkWidget * widget, gpointer * data) { gtk_widget_destroy(ports_window); ports_window = NULL; } void set_active(GtkWidget * widget, int sel) { GdkColor color_normal; GdkColor color_active; GdkColor color_prelight; if (sel == 0) { color_normal.red = 40000; color_normal.green = 40000; color_normal.blue = 40000; color_active.red = 30000; color_active.green = 30000; color_active.blue = 30000; color_prelight.red = 50000; color_prelight.green = 50000; color_prelight.blue = 50000; } else { color_normal.red = 40000; color_normal.green = 40000; color_normal.blue = 65535; color_active.red = 30000; color_active.green = 30000; color_active.blue = 45000; color_prelight.red = 50000; color_prelight.green = 50000; color_prelight.blue = 65535; } gtk_widget_modify_bg(widget, GTK_STATE_NORMAL, &color_normal); gtk_widget_modify_bg(widget, GTK_STATE_ACTIVE, &color_active); gtk_widget_modify_bg(widget, GTK_STATE_PRELIGHT, &color_prelight); } void clicked_out_L_header(GtkWidget * widget, gpointer * data) { out_selector = 0; set_active(GTK_WIDGET(column_out_L->button), 1); set_active(GTK_WIDGET(column_out_R->button), 0); } void clicked_out_R_header(GtkWidget * widget, gpointer * data) { out_selector = 1; set_active(GTK_WIDGET(column_out_L->button), 0); set_active(GTK_WIDGET(column_out_R->button), 1); } void tree_out_nb_selection_changed(GtkObject * tree, gpointer * data) { GtkTreeIter iter; GtkTreeModel * model; GtkTreeSelection * selection; gchar * str; const gchar * label; char fullname[MAXLEN]; selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree)); if (gtk_tree_selection_get_selected(selection, &model, &iter)) { gtk_tree_model_get(model, &iter, 0, &str, -1); label = gtk_label_get_text(GTK_LABEL(nb_out_labels[(int)data])); sprintf(fullname, "%s:%s", label, str); g_free(str); if (out_selector == 0) { if (jack_connect(jack_client, jack_port_name(out_L_port), fullname)) { fprintf(stderr, "Cannot connect %s to out_L. " "These ports are probably already connected.\n", fullname); } else { gtk_list_store_clear(store_out_L); scan_connections(out_L_port, store_out_L); out_selector = 1; set_active(GTK_WIDGET(column_out_L->button), 0); set_active(GTK_WIDGET(column_out_R->button), 1); } } else { if (jack_connect(jack_client, jack_port_name(out_R_port), fullname)) { fprintf(stderr, "Cannot connect %s to out_R. " "These ports are probably already connected.\n", fullname); } else { gtk_list_store_clear(store_out_R); scan_connections(out_R_port, store_out_R); out_selector = 0; set_active(GTK_WIDGET(column_out_L->button), 1); set_active(GTK_WIDGET(column_out_R->button), 0); } } } } void tree_out_L_selection_changed(GtkTreeSelection * selection, gpointer * data) { GtkTreeIter iter; GtkTreeModel * model; gchar * str; int res; if (gtk_tree_selection_get_selected(selection, &model, &iter)) { gtk_tree_model_get(model, &iter, 0, &str, -1); if ((res = jack_disconnect(jack_client, jack_port_name(out_L_port), str)) != 0) { fprintf(stderr, "ERROR: jack_disconnect() returned %d\n", res); } g_free(str); timeout_tag = aqualung_timeout_add(100, ports_timeout_callback, (gpointer)1); } } void tree_out_R_selection_changed(GtkTreeSelection *selection, gpointer * data) { GtkTreeIter iter; GtkTreeModel * model; gchar * str; int res; if (gtk_tree_selection_get_selected(selection, &model, &iter)) { gtk_tree_model_get(model, &iter, 0, &str, -1); if ((res = jack_disconnect(jack_client, jack_port_name(out_R_port), str)) != 0) { fprintf(stderr, "ERROR: jack_disconnect() returned %d\n", res); } g_free(str); timeout_tag = aqualung_timeout_add(100, ports_timeout_callback, (gpointer)2); } } void clear_outs(GtkWidget * widget, gpointer * data) { const char ** ports; int i = 0; int res; ports = jack_port_get_connections(out_L_port); if (ports) { while (ports[i] != NULL) { if ((res = jack_disconnect(jack_client, jack_port_name(out_L_port), ports[i])) != 0) { fprintf(stderr, "ERROR: jack_disconnect() returned %d\n", res); } i++; } free(ports); } i = 0; ports = jack_port_get_connections(out_R_port); if (ports) { while (ports[i] != NULL) { if ((res = jack_disconnect(jack_client, jack_port_name(out_R_port), ports[i])) != 0) { fprintf(stderr, "ERROR: jack_disconnect() returned %d\n", res); } i++; } free(ports); } gtk_list_store_clear(store_out_L); gtk_list_store_clear(store_out_R); } void scan_connections(jack_port_t * port, GtkListStore * store) { GtkTreeIter iter; const char ** ports; int i = 0; ports = jack_port_get_connections(port); if (!ports) return; while (ports[i] != NULL) { gtk_list_store_append(store, &iter); gtk_list_store_set(store, &iter, 0, ports[i], -1); i++; } free(ports); } GtkWidget * setup_tree_out(void) { GtkWidget * tree; GtkCellRenderer * renderer; GtkTreeViewColumn * column; GtkTreeSelection * select; GtkWidget * scrwin; tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store_out_nb[n_clients])); gtk_tree_view_set_enable_search(GTK_TREE_VIEW(tree), FALSE); renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes("inputs", renderer, "text", 0, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column); gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(tree), FALSE); select = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree)); gtk_tree_selection_set_mode(select, GTK_SELECTION_SINGLE); g_signal_connect(G_OBJECT(tree), "cursor-changed", G_CALLBACK(tree_out_nb_selection_changed), (gpointer *)n_clients); scrwin = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrwin), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrwin), tree); gtk_widget_set_size_request(GTK_WIDGET(scrwin), LIST_WIDTH, -1); gtk_widget_show(tree); gtk_widget_show(scrwin); return scrwin; } void setup_notebook_out(void) { const char ** ports_out; int i, j, k; char client_name[MAXLEN]; char client_name_prev[MAXLEN]; char port_name[MAXLEN]; GtkTreeIter iter; ports_out = jack_get_ports(jack_client, NULL, NULL, JackPortIsInput); for (j = 0; j < MAXLEN; j++) { client_name[j] = '\0'; client_name_prev[j] = '\0'; } i = 0; n_clients = -1; if (ports_out) { while (ports_out[i] != NULL) { /* get the client name */ j = 0; while ((ports_out[i][j] != ':') && (ports_out[i][j] != '\0')) { client_name[j] = ports_out[i][j]; j++; } client_name[j] = '\0'; /* create a new notebook page if needed */ if (strcmp(client_name, client_name_prev) != 0) { n_clients++; store_out_nb[n_clients] = gtk_list_store_new(1, G_TYPE_STRING); nb_out_labels[n_clients] = gtk_label_new(client_name); gtk_widget_show(nb_out_labels[n_clients]); gtk_notebook_insert_page(GTK_NOTEBOOK(nb_outs), GTK_WIDGET(setup_tree_out()), GTK_WIDGET(nb_out_labels[n_clients]), n_clients); } /* add the port to the list */ j = 0; while ((ports_out[i][j] != ':') && (ports_out[i][j] != '\0')) j++; if (ports_out[i][j] == '\0') fprintf(stderr, "ERROR: bad JACK port string: %s\n", ports_out[i]); else { k = 0; j++; while (ports_out[i][j] != '\0') port_name[k++] = ports_out[i][j++]; port_name[k] = '\0'; gtk_list_store_append(store_out_nb[n_clients], &iter); gtk_list_store_set(store_out_nb[n_clients], &iter, 0, port_name, -1); } strcpy(client_name_prev, client_name); i++; } free(ports_out); } } void port_setup_dialog(void) { GtkWidget * vbox; GtkWidget * table; GtkWidget * button_rescan; GtkWidget * button_close; GtkWidget * button_clear_outs; GtkWidget * frame_dl; GtkWidget * frame_dr; GtkCellRenderer * renderer_out_L; GtkCellRenderer * renderer_out_R; GtkTreeSelection * select_out_L; GtkTreeSelection * select_out_R; GtkWidget * viewp_out_L; GtkWidget * viewp_out_R; GtkWidget * hbox_L; GtkWidget * hbox_R; GtkWidget * label_L; GtkWidget * label_R; GdkColor color = { 0, 0, 0, 0 }; store_out_L = gtk_list_store_new(1, G_TYPE_STRING); store_out_R = gtk_list_store_new(1, G_TYPE_STRING); ports_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(ports_window), _("JACK Port Setup")); gtk_window_set_position(GTK_WINDOW(ports_window), GTK_WIN_POS_CENTER); gtk_window_set_modal(GTK_WINDOW(ports_window), TRUE); gtk_window_set_transient_for(GTK_WINDOW(ports_window), GTK_WINDOW(main_window)); g_signal_connect(G_OBJECT(ports_window), "delete_event", G_CALLBACK(port_window_close), NULL); vbox = gtk_vbox_new(FALSE, 0); gtk_container_add(GTK_CONTAINER(ports_window), vbox); table = gtk_table_new(2, 2, FALSE); gtk_box_pack_start(GTK_BOX(vbox), table, TRUE, TRUE, 2); button_rescan = gui_stock_label_button(_("Rescan"), GTK_STOCK_REFRESH); gtk_table_attach(GTK_TABLE(table), button_rescan, 0, 1, 1, 2, GTK_FILL | GTK_EXPAND, GTK_FILL, 5, 5); g_signal_connect(G_OBJECT(button_rescan), "clicked", G_CALLBACK(clicked_rescan), NULL); button_close = gtk_button_new_from_stock (GTK_STOCK_CLOSE); gtk_table_attach(GTK_TABLE(table), button_close, 1, 2, 1, 2, GTK_FILL | GTK_EXPAND, GTK_FILL, 5, 5); g_signal_connect(G_OBJECT(button_close), "clicked", G_CALLBACK(ports_clicked_close), NULL); frame_dl = gtk_frame_new(_("Outputs")); gtk_table_attach(GTK_TABLE(table), frame_dl, 0, 1, 0, 1, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 5, 5); frame_dr = gtk_frame_new(_("Available connections")); gtk_table_attach(GTK_TABLE(table), frame_dr, 1, 2, 0, 1, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 5, 5); vbox_dl = gtk_vbox_new(FALSE, 5); gtk_container_set_border_width(GTK_CONTAINER(vbox_dl), 8); gtk_container_add(GTK_CONTAINER(frame_dl), vbox_dl); vbox_dr = gtk_vbox_new(FALSE, 5); gtk_container_set_border_width(GTK_CONTAINER(vbox_dr), 8); gtk_container_add(GTK_CONTAINER(frame_dr), vbox_dr); button_clear_outs = gui_stock_label_button(_("Clear connections"), GTK_STOCK_CLEAR); gtk_box_pack_start(GTK_BOX(vbox_dl), button_clear_outs, FALSE, TRUE, 2); g_signal_connect(G_OBJECT(button_clear_outs), "clicked", G_CALLBACK(clear_outs), NULL); nb_outs = gtk_notebook_new(); gtk_box_pack_start(GTK_BOX(vbox_dr), nb_outs, TRUE, TRUE, 2); scan_connections(out_L_port, store_out_L); scan_connections(out_R_port, store_out_R); tree_out_L = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store_out_L)); gtk_tree_view_set_enable_search(GTK_TREE_VIEW(tree_out_L), FALSE); tree_out_R = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store_out_R)); gtk_tree_view_set_enable_search(GTK_TREE_VIEW(tree_out_R), FALSE); renderer_out_L = gtk_cell_renderer_text_new(); renderer_out_R = gtk_cell_renderer_text_new(); column_out_L = gtk_tree_view_column_new_with_attributes(NULL, renderer_out_L, "text", 0, NULL); column_out_R = gtk_tree_view_column_new_with_attributes(NULL, renderer_out_R, "text", 0, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(tree_out_L), column_out_L); gtk_tree_view_append_column(GTK_TREE_VIEW(tree_out_R), column_out_R); g_signal_connect(G_OBJECT(column_out_L->button), "clicked", G_CALLBACK(clicked_out_L_header), NULL); g_signal_connect(G_OBJECT(column_out_R->button), "clicked", G_CALLBACK(clicked_out_R_header), NULL); gtk_widget_set_name(column_out_L->button, "nostyle"); gtk_widget_set_name(column_out_R->button, "nostyle"); select_out_L = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_out_L)); gtk_tree_selection_set_mode(select_out_L, GTK_SELECTION_SINGLE); g_signal_connect(G_OBJECT(select_out_L), "changed", G_CALLBACK(tree_out_L_selection_changed), NULL); select_out_R = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_out_R)); gtk_tree_selection_set_mode(select_out_R, GTK_SELECTION_SINGLE); g_signal_connect(G_OBJECT(select_out_R), "changed", G_CALLBACK(tree_out_R_selection_changed), NULL); gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(tree_out_L), TRUE); gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(tree_out_R), TRUE); viewp_out_L = gtk_viewport_new(NULL, NULL); gtk_viewport_set_shadow_type(GTK_VIEWPORT(viewp_out_L), GTK_SHADOW_IN); gtk_container_add(GTK_CONTAINER(viewp_out_L), tree_out_L); gtk_widget_set_size_request(GTK_WIDGET(viewp_out_L), LIST_WIDTH, LIST_HEIGHT); viewp_out_R = gtk_viewport_new(NULL, NULL); gtk_viewport_set_shadow_type(GTK_VIEWPORT(viewp_out_R), GTK_SHADOW_IN); gtk_container_add(GTK_CONTAINER(viewp_out_R), tree_out_R); gtk_widget_set_size_request(GTK_WIDGET(viewp_out_R), LIST_WIDTH, LIST_HEIGHT); gtk_box_pack_start(GTK_BOX(vbox_dl), viewp_out_L, TRUE, TRUE, 2); gtk_box_pack_start(GTK_BOX(vbox_dl), viewp_out_R, TRUE, TRUE, 2); setup_notebook_out(); set_active(GTK_WIDGET(column_out_L->button), TRUE); set_active(GTK_WIDGET(column_out_R->button), FALSE); gtk_widget_show_all(ports_window); gtk_widget_destroy(GTK_BIN(column_out_L->button)->child); gtk_widget_destroy(GTK_BIN(column_out_R->button)->child); hbox_L = gtk_hbox_new(FALSE, 0); hbox_R = gtk_hbox_new(FALSE, 0); label_L = gtk_label_new(_(" out L")); label_R = gtk_label_new(_(" out R")); gtk_container_add(GTK_CONTAINER(column_out_L->button), hbox_L); gtk_container_add(GTK_CONTAINER(column_out_R->button), hbox_R); gtk_box_pack_start(GTK_BOX(hbox_L), label_L, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox_R), label_R, FALSE, FALSE, 0); gtk_widget_modify_fg(label_L, GTK_STATE_NORMAL, &color); gtk_widget_modify_fg(label_L, GTK_STATE_PRELIGHT, &color); gtk_widget_modify_fg(label_L, GTK_STATE_ACTIVE, &color); gtk_widget_modify_fg(label_R, GTK_STATE_NORMAL, &color); gtk_widget_modify_fg(label_R, GTK_STATE_PRELIGHT, &color); gtk_widget_modify_fg(label_R, GTK_STATE_ACTIVE, &color); gtk_widget_show_all(hbox_L); gtk_widget_show_all(hbox_R); } #endif /* HAVE_JACK */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/rb.h0000644000175000001440000001602310661272624012465 00000000000000/* Copyright (C) 2000 Paul Davis Copyright (C) 2003 Rohan Drape This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. $Id: rb.h 781 2007-08-17 10:13:50Z tszilagyi $ */ #ifndef _RINGBUFFER_H #define _RINGBUFFER_H #include #ifdef __cplusplus extern "C" { #endif /** @file ringbuffer.h * * A set of library functions to make lock-free ringbuffers available * to JACK clients. The `capture_client.c' (in the example_clients * directory) is a fully functioning user of this API. * * The key attribute of a ringbuffer is that it can be safely accessed * by two threads simultaneously -- one reading from the buffer and * the other writing to it -- without using any synchronization or * mutual exclusion primitives. For this to work correctly, there can * only be a single reader and a single writer thread. Their * identities cannot be interchanged. */ typedef struct { char *buf; size_t len; } rb_data_t ; typedef struct { char *buf; volatile size_t write_ptr; volatile size_t read_ptr; size_t size; size_t size_mask; int mlocked; } rb_t ; /** * Allocates a ringbuffer data structure of a specified size. The * caller must arrange for a call to rb_free() to release * the memory associated with the ringbuffer. * * @param sz the ringbuffer size in bytes. * * @return a pointer to a new rb_t, if successful; NULL * otherwise. */ rb_t *rb_create(size_t sz); /** * Frees the ringbuffer data structure allocated by an earlier call to * rb_create(). * * @param rb a pointer to the ringbuffer structure. */ void rb_free(rb_t *rb); /** * Fill a data structure with a description of the current readable * data held in the ringbuffer. This description is returned in a two * element array of rb_data_t. Two elements are needed * because the data to be read may be split across the end of the * ringbuffer. * * The first element will always contain a valid @a len field, which * may be zero or greater. If the @a len field is non-zero, then data * can be read in a contiguous fashion using the address given in the * corresponding @a buf field. * * If the second element has a non-zero @a len field, then a second * contiguous stretch of data can be read from the address given in * its corresponding @a buf field. * * @param rb a pointer to the ringbuffer structure. * @param vec a pointer to a 2 element array of rb_data_t. * */ void rb_get_read_vector(const rb_t *rb, rb_data_t *vec); /** * Fill a data structure with a description of the current writable * space in the ringbuffer. The description is returned in a two * element array of rb_data_t. Two elements are needed * because the space available for writing may be split across the end * of the ringbuffer. * * The first element will always contain a valid @a len field, which * may be zero or greater. If the @a len field is non-zero, then data * can be written in a contiguous fashion using the address given in * the corresponding @a buf field. * * If the second element has a non-zero @a len field, then a second * contiguous stretch of data can be written to the address given in * the corresponding @a buf field. * * @param rb a pointer to the ringbuffer structure. * @param vec a pointer to a 2 element array of rb_data_t. */ void rb_get_write_vector(const rb_t *rb, rb_data_t *vec); /** * Read data from the ringbuffer. * * @param rb a pointer to the ringbuffer structure. * @param dest a pointer to a buffer where data read from the * ringbuffer will go. * @param cnt the number of bytes to read. * * @return the number of bytes read, which may range from 0 to cnt. */ size_t rb_read(rb_t *rb, char *dest, size_t cnt); /** * Read data from the ringbuffer. Opposed to rb_read() * this function does not move the read pointer. Thus it's * a convenient way to inspect data in the ringbuffer in a * continous fashion. The price is that the data is copied * into a user provided buffer. For "raw" non-copy inspection * of the data in the ringbuffer use rb_get_read_vector(). * * @param rb a pointer to the ringbuffer structure. * @param dest a pointer to a buffer where data read from the * ringbuffer will go. * @param cnt the number of bytes to read. * * @return the number of bytes read, which may range from 0 to cnt. */ size_t rb_peek(rb_t *rb, char *dest, size_t cnt); /** * Advance the read pointer. * * After data have been read from the ringbuffer using the pointers * returned by rb_get_read_vector(), use this function to * advance the buffer pointers, making that space available for future * write operations. * * @param rb a pointer to the ringbuffer structure. * @param cnt the number of bytes read. */ void rb_read_advance(rb_t *rb, size_t cnt); /** * Return the number of bytes available for reading. * * @param rb a pointer to the ringbuffer structure. * * @return the number of bytes available to read. */ size_t rb_read_space(const rb_t *rb); /** * Lock a ringbuffer data block into memory. * * Uses the mlock() system call. This is not a realtime operation. * * @param rb a pointer to the ringbuffer structure. */ int rb_mlock(rb_t *rb); /** * Reset the read and write pointers, making an empty buffer. * * This is not thread safe. * * @param rb a pointer to the ringbuffer structure. */ void rb_reset(rb_t *rb); /** * Write data into the ringbuffer. * * @param rb a pointer to the ringbuffer structure. * @param src a pointer to the data to be written to the ringbuffer. * @param cnt the number of bytes to write. * * @return the number of bytes write, which may range from 0 to cnt */ size_t rb_write(rb_t *rb, const char *src, size_t cnt); /** * Advance the write pointer. * * After data have been written the ringbuffer using the pointers * returned by rb_get_write_vector(), use this function * to advance the buffer pointer, making the data available for future * read operations. * * @param rb a pointer to the ringbuffer structure. * @param cnt the number of bytes written. */ void rb_write_advance(rb_t *rb, size_t cnt); /** * Return the number of bytes available for writing. * * @param rb a pointer to the ringbuffer structure. * * @return the amount of free space (in bytes) available for writing. */ size_t rb_write_space(const rb_t *rb); #ifdef __cplusplus } /* extern "C" */ #endif #endif /* _RINGBUFFER_H */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/rb.c0000644000175000001440000001674110612341733012461 00000000000000/* Copyright (C) 2000 Paul Davis Copyright (C) 2003 Rohan Drape This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ISO/POSIX C version of Paul Davis's lock free ringbuffer C++ code. This is safe for the case of one read thread and one write thread. */ #include #include #include #ifdef USE_MLOCK #include #endif /* USE_MLOCK */ #include "rb.h" /* Create a new ringbuffer to hold at least `sz' bytes of data. The actual buffer size is rounded up to the next power of two. */ rb_t * rb_create (size_t sz) { int power_of_two; rb_t *rb; rb = calloc (1, sizeof (rb_t)); for (power_of_two = 1; 1 << power_of_two < sz; power_of_two++); rb->size = 1 << power_of_two; rb->size_mask = rb->size; rb->size_mask -= 1; rb->write_ptr = 0; rb->read_ptr = 0; rb->buf = calloc (1, rb->size); rb->mlocked = 0; return rb; } /* Free all data associated with the ringbuffer `rb'. */ void rb_free (rb_t * rb) { #ifdef USE_MLOCK if (rb->mlocked) { munlock (rb->buf, rb->size); } #endif /* USE_MLOCK */ free (rb->buf); free (rb); } /* Lock the data block of `rb' using the system call 'mlock'. */ int rb_mlock (rb_t * rb) { #ifdef USE_MLOCK if (mlock (rb->buf, rb->size)) { return -1; } #endif /* USE_MLOCK */ rb->mlocked = 1; return 0; } /* Reset the read and write pointers to zero. This is not thread safe. */ void rb_reset (rb_t * rb) { rb->read_ptr = 0; rb->write_ptr = 0; } /* Return the number of bytes available for reading. This is the number of bytes in front of the read pointer and behind the write pointer. */ size_t rb_read_space (const rb_t * rb) { size_t w, r; w = rb->write_ptr; r = rb->read_ptr; if (w > r) { return w - r; } else { return (w - r + rb->size) & rb->size_mask; } } /* Return the number of bytes available for writing. This is the number of bytes in front of the write pointer and behind the read pointer. */ size_t rb_write_space (const rb_t * rb) { size_t w, r; w = rb->write_ptr; r = rb->read_ptr; if (w > r) { return ((r - w + rb->size) & rb->size_mask) - 1; } else if (w < r) { return (r - w) - 1; } else { return rb->size - 1; } } /* The copying data reader. Copy at most `cnt' bytes from `rb' to `dest'. Returns the actual number of bytes copied. */ size_t rb_read (rb_t * rb, char *dest, size_t cnt) { size_t free_cnt; size_t cnt2; size_t to_read; size_t n1, n2; if ((free_cnt = rb_read_space (rb)) == 0) { return 0; } to_read = cnt > free_cnt ? free_cnt : cnt; cnt2 = rb->read_ptr + to_read; if (cnt2 > rb->size) { n1 = rb->size - rb->read_ptr; n2 = cnt2 & rb->size_mask; } else { n1 = to_read; n2 = 0; } memcpy (dest, &(rb->buf[rb->read_ptr]), n1); rb->read_ptr += n1; rb->read_ptr &= rb->size_mask; if (n2) { memcpy (dest + n1, &(rb->buf[rb->read_ptr]), n2); rb->read_ptr += n2; rb->read_ptr &= rb->size_mask; } return to_read; } /* The copying data reader w/o read pointer advance. Copy at most `cnt' bytes from `rb' to `dest'. Returns the actual number of bytes copied. */ size_t rb_peek (rb_t * rb, char *dest, size_t cnt) { size_t free_cnt; size_t cnt2; size_t to_read; size_t n1, n2; size_t tmp_read_ptr; tmp_read_ptr = rb->read_ptr; if ((free_cnt = rb_read_space (rb)) == 0) { return 0; } to_read = cnt > free_cnt ? free_cnt : cnt; cnt2 = tmp_read_ptr + to_read; if (cnt2 > rb->size) { n1 = rb->size - tmp_read_ptr; n2 = cnt2 & rb->size_mask; } else { n1 = to_read; n2 = 0; } memcpy (dest, &(rb->buf[tmp_read_ptr]), n1); tmp_read_ptr += n1; tmp_read_ptr &= rb->size_mask; if (n2) { memcpy (dest + n1, &(rb->buf[tmp_read_ptr]), n2); tmp_read_ptr += n2; tmp_read_ptr &= rb->size_mask; } return to_read; } /* The copying data writer. Copy at most `cnt' bytes to `rb' from `src'. Returns the actual number of bytes copied. */ size_t rb_write (rb_t * rb, const char *src, size_t cnt) { size_t free_cnt; size_t cnt2; size_t to_write; size_t n1, n2; if ((free_cnt = rb_write_space (rb)) == 0) { return 0; } to_write = cnt > free_cnt ? free_cnt : cnt; cnt2 = rb->write_ptr + to_write; if (cnt2 > rb->size) { n1 = rb->size - rb->write_ptr; n2 = cnt2 & rb->size_mask; } else { n1 = to_write; n2 = 0; } memcpy (&(rb->buf[rb->write_ptr]), src, n1); rb->write_ptr += n1; rb->write_ptr &= rb->size_mask; if (n2) { memcpy (&(rb->buf[rb->write_ptr]), src + n1, n2); rb->write_ptr += n2; rb->write_ptr &= rb->size_mask; } return to_write; } /* Advance the read pointer `cnt' places. */ void rb_read_advance (rb_t * rb, size_t cnt) { rb->read_ptr += cnt; rb->read_ptr &= rb->size_mask; } /* Advance the write pointer `cnt' places. */ void rb_write_advance (rb_t * rb, size_t cnt) { rb->write_ptr += cnt; rb->write_ptr &= rb->size_mask; } /* The non-copying data reader. `vec' is an array of two places. Set the values at `vec' to hold the current readable data at `rb'. If the readable data is in one segment the second segment has zero length. */ void rb_get_read_vector (const rb_t * rb, rb_data_t * vec) { size_t free_cnt; size_t cnt2; size_t w, r; w = rb->write_ptr; r = rb->read_ptr; if (w > r) { free_cnt = w - r; } else { free_cnt = (w - r + rb->size) & rb->size_mask; } cnt2 = r + free_cnt; if (cnt2 > rb->size) { /* Two part vector: the rest of the buffer after the current write ptr, plus some from the start of the buffer. */ vec[0].buf = &(rb->buf[r]); vec[0].len = rb->size - r; vec[1].buf = rb->buf; vec[1].len = cnt2 & rb->size_mask; } else { /* Single part vector: just the rest of the buffer */ vec[0].buf = &(rb->buf[r]); vec[0].len = free_cnt; vec[1].len = 0; } } /* The non-copying data writer. `vec' is an array of two places. Set the values at `vec' to hold the current writeable data at `rb'. If the writeable data is in one segment the second segment has zero length. */ void rb_get_write_vector (const rb_t * rb, rb_data_t * vec) { size_t free_cnt; size_t cnt2; size_t w, r; w = rb->write_ptr; r = rb->read_ptr; if (w > r) { free_cnt = ((r - w + rb->size) & rb->size_mask) - 1; } else if (w < r) { free_cnt = (r - w) - 1; } else { free_cnt = rb->size - 1; } cnt2 = w + free_cnt; if (cnt2 > rb->size) { /* Two part vector: the rest of the buffer after the current write ptr, plus some from the start of the buffer. */ vec[0].buf = &(rb->buf[w]); vec[0].len = rb->size - w; vec[1].buf = rb->buf; vec[1].len = cnt2 & rb->size_mask; } else { vec[0].buf = &(rb->buf[w]); vec[0].len = free_cnt; vec[1].len = 0; } } // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/search.h0000644000175000001440000000256610612341733013330 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: search.h 524 2007-01-06 15:39:18Z pasp $ */ #ifndef _SEARCH_H #define _SEARCH_H /* search flags */ #define SEARCH_F_CS (1 << 0) /* case sensitive */ #define SEARCH_F_EM (1 << 1) /* exact matches only */ #define SEARCH_F_SF (1 << 2) /* select first and close */ #define SEARCH_F_AN (1 << 3) /* artist names */ #define SEARCH_F_RT (1 << 4) /* record titles */ #define SEARCH_F_TT (1 << 5) /* track titles */ #define SEARCH_F_CO (1 << 6) /* comments */ void search_dialog(void); #endif /* _SEARCH_H */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/search.c0000644000175000001440000005115310733755150013325 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: search.c 952 2007-12-24 13:56:27Z peterszilagyi $ */ #include #include #include #include #include #include #include "common.h" #include "utils_gui.h" #include "music_browser.h" #include "store_file.h" #include "gui_main.h" #include "i18n.h" #include "options.h" #include "search.h" extern options_t options; extern GtkTreeStore * music_store; extern GtkWidget * music_tree; extern GtkWidget * browser_window; GtkWidget * search_window = NULL; GtkWidget * searchkey_entry; GtkWidget * check_case; GtkWidget * check_exact; GtkWidget * check_sfac; GtkWidget * check_artist; GtkWidget * check_record; GtkWidget * check_track; GtkWidget * check_comment; GtkWidget * sres_list; GtkListStore * search_store; GtkTreeSelection * search_select; int casesens; int exactonly; int selectfc; int artist_yes; int record_yes; int track_yes; int comment_yes; static void get_toggle_buttons_state(void) { casesens = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check_case)) ? 1 : 0; exactonly = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check_exact)) ? 1 : 0; selectfc = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check_sfac)) ? 1 : 0; artist_yes = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check_artist)) ? 1 : 0; record_yes = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check_record)) ? 1 : 0; track_yes = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check_track)) ? 1 : 0; comment_yes = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check_comment)) ? 1 : 0; } void clear_search_store(void) { int i; GtkTreeIter iter; i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(search_store), &iter, NULL, i++)) { gpointer gptr; GtkTreePath * path; gtk_tree_model_get(GTK_TREE_MODEL(search_store), &iter, 3, &gptr, -1); path = (GtkTreePath *)gptr; if (path != NULL) { gtk_tree_path_free(path); } } gtk_list_store_clear(search_store); } static gint close_button_clicked(GtkWidget * widget, gpointer data) { get_toggle_buttons_state(); options.search_ms_flags = (casesens * SEARCH_F_CS) | (exactonly * SEARCH_F_EM) | (selectfc * SEARCH_F_SF) | (artist_yes * SEARCH_F_AN) | (record_yes * SEARCH_F_RT) | (track_yes * SEARCH_F_TT) | (comment_yes * SEARCH_F_CO); clear_search_store(); gtk_widget_destroy(search_window); search_window = NULL; return TRUE; } int search_window_close(GtkWidget * widget, gpointer * data) { get_toggle_buttons_state(); options.search_ms_flags = (casesens * SEARCH_F_CS) | (exactonly * SEARCH_F_EM) | (selectfc * SEARCH_F_SF) | (artist_yes * SEARCH_F_AN) | (record_yes * SEARCH_F_RT) | (track_yes * SEARCH_F_TT) | (comment_yes * SEARCH_F_CO); clear_search_store(); search_window = NULL; return 0; } static gint sfac_clicked(GtkWidget * widget, gpointer data) { get_toggle_buttons_state(); if (selectfc) { gtk_widget_hide(sres_list); gtk_window_resize(GTK_WINDOW(search_window), 420, 215); } else { gtk_window_resize(GTK_WINDOW(search_window), 420, 430); gtk_widget_show(sres_list); } return TRUE; } static gint search_button_clicked(GtkWidget * widget, gpointer data) { int valid; const char * key_string = gtk_entry_get_text(GTK_ENTRY(searchkey_entry)); char key[MAXLEN]; GPatternSpec * pattern; int h, i, j, k; GtkTreeIter store_iter; GtkTreeIter artist_iter; GtkTreeIter record_iter; GtkTreeIter track_iter; GtkTreeIter sfac_iter; get_toggle_buttons_state(); clear_search_store(); valid = 0; for (i = 0; key_string[i] != '\0'; i++) { if ((key_string[i] != '?') && (key_string[i] != '*')) { valid = 1; break; } } if (!valid) { return TRUE; } if (!casesens) { key_string = g_utf8_strup(key_string, -1); } if (exactonly) { strcpy(key, key_string); } else { snprintf(key, MAXLEN-1, "*%s*", key_string); } pattern = g_pattern_spec_new(key); h = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &store_iter, NULL, h++)) { if (iter_get_store_type(&store_iter) != STORE_TYPE_FILE) { continue; } i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &artist_iter, &store_iter, i++)) { char * artist_name; artist_data_t * artist_data; gtk_tree_model_get(GTK_TREE_MODEL(music_store), &artist_iter, MS_COL_NAME, &artist_name, MS_COL_DATA, &artist_data, -1); if (artist_yes) { char * tmp = NULL; if (casesens) { tmp = strdup(artist_name); } else { tmp = g_utf8_strup(artist_name, -1); } if (g_pattern_match_string(pattern, tmp)) { GtkTreeIter iter; GtkTreePath * path; path = gtk_tree_model_get_path(GTK_TREE_MODEL(music_store), &artist_iter); gtk_list_store_append(search_store, &iter); gtk_list_store_set(search_store, &iter, 0, artist_name, 1, "", 2, "", 3, (gpointer)path, -1); } g_free(tmp); } if (comment_yes && artist_data->comment != NULL) { char * tmp = NULL; if (casesens) { tmp = strdup(artist_data->comment); } else { tmp = g_utf8_strup(artist_data->comment, -1); } if (g_pattern_match_string(pattern, tmp)) { GtkTreeIter iter; GtkTreePath * path; path = gtk_tree_model_get_path(GTK_TREE_MODEL(music_store), &artist_iter); gtk_list_store_append(search_store, &iter); gtk_list_store_set(search_store, &iter, 0, artist_name, 1, "", 2, "", 3, (gpointer)path, -1); } g_free(tmp); } j = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &record_iter, &artist_iter, j++)) { char * record_name; record_data_t * record_data; gtk_tree_model_get(GTK_TREE_MODEL(music_store), &record_iter, MS_COL_NAME, &record_name, MS_COL_DATA, &record_data, -1); if (record_yes) { char * tmp = NULL; if (casesens) { tmp = strdup(record_name); } else { tmp = g_utf8_strup(record_name, -1); } if (g_pattern_match_string(pattern, tmp)) { GtkTreeIter iter; GtkTreePath * path; path = gtk_tree_model_get_path(GTK_TREE_MODEL(music_store), &record_iter); gtk_list_store_append(search_store, &iter); gtk_list_store_set(search_store, &iter, 0, artist_name, 1, record_name, 2, "", 3, (gpointer)path, -1); } g_free(tmp); } if (comment_yes && record_data->comment != NULL) { char * tmp = NULL; if (casesens) { tmp = strdup(record_data->comment); } else { tmp = g_utf8_strup(record_data->comment, -1); } if (g_pattern_match_string(pattern, tmp)) { GtkTreeIter iter; GtkTreePath * path; path = gtk_tree_model_get_path(GTK_TREE_MODEL(music_store), &record_iter); gtk_list_store_append(search_store, &iter); gtk_list_store_set(search_store, &iter, 0, artist_name, 1, record_name, 2, "", 3, (gpointer)path, -1); } g_free(tmp); } k = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &track_iter, &record_iter, k++)) { char * track_name; track_data_t * track_data; gtk_tree_model_get(GTK_TREE_MODEL(music_store), &track_iter, MS_COL_NAME, &track_name, MS_COL_DATA, &track_data, -1); if (track_yes) { char * tmp = NULL; if (casesens) { tmp = strdup(track_name); } else { tmp = g_utf8_strup(track_name, -1); } if (g_pattern_match_string(pattern, tmp)) { GtkTreeIter iter; GtkTreePath * path; path = gtk_tree_model_get_path(GTK_TREE_MODEL(music_store), &track_iter); gtk_list_store_append(search_store, &iter); gtk_list_store_set(search_store, &iter, 0, artist_name, 1, record_name, 2, track_name, 3, (gpointer)path, -1); } g_free(tmp); } if (comment_yes && track_data->comment != NULL) { char * tmp = NULL; if (casesens) { tmp = strdup(track_data->comment); } else { tmp = g_utf8_strup(track_data->comment, -1); } if (g_pattern_match_string(pattern, tmp)) { GtkTreeIter iter; GtkTreePath * path; path = gtk_tree_model_get_path(GTK_TREE_MODEL(music_store), &track_iter); gtk_list_store_append(search_store, &iter); gtk_list_store_set(search_store, &iter, 0, artist_name, 1, record_name, 2, track_name, 3, (gpointer)path, -1); } g_free(tmp); } g_free(track_name); } g_free(record_name); } g_free(artist_name); } } g_pattern_spec_free(pattern); if (selectfc) { if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(search_store), &sfac_iter) == TRUE) { gtk_tree_selection_select_iter(search_select, &sfac_iter); } close_button_clicked(NULL, NULL); } return TRUE; } void search_selection_changed(GtkTreeSelection * treeselection, gpointer user_data) { GtkTreeIter iter; GtkTreePath * path; gpointer gptr; if (!gtk_tree_selection_get_selected(search_select, NULL, &iter)) { return; } gtk_tree_model_get(GTK_TREE_MODEL(search_store), &iter, 3, &gptr, -1); path = (GtkTreePath *)gptr; gtk_tree_view_collapse_all(GTK_TREE_VIEW(music_tree)); gtk_tree_view_expand_to_path(GTK_TREE_VIEW(music_tree), path); gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(music_tree), path, NULL, TRUE, 0.5f, 0.5f); gtk_tree_view_set_cursor(GTK_TREE_VIEW(music_tree), path, NULL, FALSE); } gint search_window_key_pressed(GtkWidget * widget, GdkEventKey * kevent) { switch (kevent->keyval) { case GDK_Escape: close_button_clicked(NULL, NULL); return TRUE; break; case GDK_Return: case GDK_KP_Enter: search_button_clicked(NULL, NULL); return TRUE; break; } return FALSE; } void search_dialog(void) { GtkWidget * vbox; GtkWidget * hbox; GtkWidget * label; GtkWidget * button; GtkWidget * table; GtkWidget * hbuttonbox; GtkWidget * search_viewport; GtkWidget * search_scrwin; GtkWidget * search_list; GtkCellRenderer * search_renderer; GtkTreeViewColumn * search_column; if (search_window != NULL) { return; } search_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(search_window), _("Search the Music Store")); gtk_window_set_position(GTK_WINDOW(search_window), GTK_WIN_POS_CENTER_ON_PARENT); gtk_window_set_transient_for(GTK_WINDOW(search_window), GTK_WINDOW(browser_window)); gtk_window_set_modal(GTK_WINDOW(search_window), TRUE); g_signal_connect(G_OBJECT(search_window), "delete_event", G_CALLBACK(search_window_close), NULL); g_signal_connect(G_OBJECT(search_window), "key_press_event", G_CALLBACK(search_window_key_pressed), NULL); gtk_container_set_border_width(GTK_CONTAINER(search_window), 5); vbox = gtk_vbox_new(FALSE, 0); gtk_widget_show(vbox); gtk_container_add(GTK_CONTAINER(search_window), vbox); hbox = gtk_hbox_new(FALSE, 0); gtk_widget_show(hbox); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 3); label = gtk_label_new(_("Key: ")); gtk_widget_show(label); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5); searchkey_entry = gtk_entry_new(); gtk_widget_show(searchkey_entry); gtk_box_pack_start(GTK_BOX(hbox), searchkey_entry, TRUE, TRUE, 5); table = gtk_table_new(5, 2, FALSE); gtk_widget_show(table); gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, TRUE, 3); check_case = gtk_check_button_new_with_label(_("Case sensitive")); gtk_widget_show(check_case); gtk_widget_set_name(check_case, "check_on_window"); gtk_table_attach(GTK_TABLE(table), check_case, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 1, 5); check_exact = gtk_check_button_new_with_label(_("Exact matches only")); gtk_widget_show(check_exact); gtk_widget_set_name(check_exact, "check_on_window"); gtk_table_attach(GTK_TABLE(table), check_exact, 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 1, 5); check_sfac = gtk_check_button_new_with_label(_("Select first and close window")); gtk_widget_show(check_sfac); gtk_widget_set_name(check_sfac, "check_on_window"); g_signal_connect(G_OBJECT(check_sfac), "clicked", G_CALLBACK(sfac_clicked), NULL); gtk_table_attach(GTK_TABLE(table), check_sfac, 0, 1, 1, 2, GTK_EXPAND | GTK_FILL, GTK_FILL, 1, 5); hbox = gtk_hbox_new(FALSE, 0); gtk_widget_show(hbox); label = gtk_label_new(_("Search in:")); gtk_widget_show(label); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 3); gtk_table_attach(GTK_TABLE(table), hbox, 0, 2, 2, 3, GTK_EXPAND | GTK_FILL, GTK_FILL, 1, 5); check_artist = gtk_check_button_new_with_label(_("Artist names")); gtk_widget_show(check_artist); gtk_widget_set_name(check_artist, "check_on_window"); gtk_table_attach(GTK_TABLE(table), check_artist, 0, 1, 3, 4, GTK_EXPAND | GTK_FILL, GTK_FILL, 1, 1); check_record = gtk_check_button_new_with_label(_("Record titles")); gtk_widget_show(check_record); gtk_widget_set_name(check_record, "check_on_window"); gtk_table_attach(GTK_TABLE(table), check_record, 0, 1, 4, 5, GTK_EXPAND | GTK_FILL, GTK_FILL, 1, 1); check_track = gtk_check_button_new_with_label(_("Track titles")); gtk_widget_show(check_track); gtk_widget_set_name(check_track, "check_on_window"); gtk_table_attach(GTK_TABLE(table), check_track, 1, 2, 3, 4, GTK_EXPAND | GTK_FILL, GTK_FILL, 1, 1); check_comment = gtk_check_button_new_with_label(_("Comments")); gtk_widget_show(check_comment); gtk_widget_set_name(check_comment, "check_on_window"); gtk_table_attach(GTK_TABLE(table), check_comment, 1, 2, 4, 5, GTK_EXPAND | GTK_FILL, GTK_FILL, 1, 1); hbox = sres_list = gtk_hbox_new(FALSE, 0); gtk_widget_show(hbox); gtk_container_set_border_width(GTK_CONTAINER(hbox), 3); gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 3); search_viewport = gtk_viewport_new(NULL, NULL); gtk_widget_show(search_viewport); gtk_box_pack_start(GTK_BOX(hbox), search_viewport, TRUE, TRUE, 0); search_scrwin = gtk_scrolled_window_new(NULL, NULL); gtk_widget_show(search_scrwin); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(search_scrwin), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_container_add(GTK_CONTAINER(search_viewport), search_scrwin); search_store = gtk_list_store_new(4, G_TYPE_STRING, /* artist */ G_TYPE_STRING, /* record */ G_TYPE_STRING, /* track */ G_TYPE_POINTER); /* * GtkTreePath */ gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(search_store), 0, GTK_SORT_ASCENDING); search_list = gtk_tree_view_new_with_model(GTK_TREE_MODEL(search_store)); gtk_widget_show(search_list); gtk_widget_set_size_request(search_list, 400, 200); gtk_container_add(GTK_CONTAINER(search_scrwin), search_list); search_select = gtk_tree_view_get_selection(GTK_TREE_VIEW(search_list)); gtk_tree_selection_set_mode(search_select, GTK_SELECTION_SINGLE); g_signal_connect(G_OBJECT(search_select), "changed", G_CALLBACK(search_selection_changed), NULL); search_renderer = gtk_cell_renderer_text_new(); search_column = gtk_tree_view_column_new_with_attributes(_("Artist"), search_renderer, "text", 0, NULL); gtk_tree_view_column_set_sizing(GTK_TREE_VIEW_COLUMN(search_column), GTK_TREE_VIEW_COLUMN_AUTOSIZE); gtk_tree_view_column_set_resizable(GTK_TREE_VIEW_COLUMN(search_column), TRUE); gtk_tree_view_column_set_sort_column_id(GTK_TREE_VIEW_COLUMN(search_column), 0); gtk_tree_view_append_column(GTK_TREE_VIEW(search_list), search_column); search_renderer = gtk_cell_renderer_text_new(); search_column = gtk_tree_view_column_new_with_attributes(_("Record"), search_renderer, "text", 1, NULL); gtk_tree_view_column_set_sizing(GTK_TREE_VIEW_COLUMN(search_column), GTK_TREE_VIEW_COLUMN_AUTOSIZE); gtk_tree_view_column_set_resizable(GTK_TREE_VIEW_COLUMN(search_column), TRUE); gtk_tree_view_column_set_sort_column_id(GTK_TREE_VIEW_COLUMN(search_column), 1); gtk_tree_view_append_column(GTK_TREE_VIEW(search_list), search_column); search_renderer = gtk_cell_renderer_text_new(); search_column = gtk_tree_view_column_new_with_attributes(_("Track"), search_renderer, "text", 2, NULL); gtk_tree_view_column_set_sizing(GTK_TREE_VIEW_COLUMN(search_column), GTK_TREE_VIEW_COLUMN_AUTOSIZE); gtk_tree_view_column_set_resizable(GTK_TREE_VIEW_COLUMN(search_column), TRUE); gtk_tree_view_column_set_sort_column_id(GTK_TREE_VIEW_COLUMN(search_column), 2); gtk_tree_view_append_column(GTK_TREE_VIEW(search_list), search_column); hbuttonbox = gtk_hbutton_box_new(); gtk_widget_show (hbuttonbox); gtk_box_set_spacing(GTK_BOX(hbuttonbox), 8); gtk_box_pack_end(GTK_BOX(vbox), hbuttonbox, FALSE, TRUE, 0); gtk_button_box_set_layout(GTK_BUTTON_BOX(hbuttonbox), GTK_BUTTONBOX_END); button = gui_stock_label_button(_("Search"), GTK_STOCK_FIND); gtk_widget_show(button); gtk_container_add(GTK_CONTAINER(hbuttonbox), button); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(search_button_clicked), NULL); button = gtk_button_new_from_stock (GTK_STOCK_CLOSE); gtk_widget_show(button); gtk_container_add(GTK_CONTAINER(hbuttonbox), button); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(close_button_clicked), NULL); if (options.search_ms_flags & SEARCH_F_CS) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_case), TRUE); if (options.search_ms_flags & SEARCH_F_EM) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_exact), TRUE); if (options.search_ms_flags & SEARCH_F_SF) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_sfac), TRUE); if (options.search_ms_flags & SEARCH_F_AN) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_artist), TRUE); if (options.search_ms_flags & SEARCH_F_RT) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_record), TRUE); if (options.search_ms_flags & SEARCH_F_TT) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_track), TRUE); if (options.search_ms_flags & SEARCH_F_CO) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_comment), TRUE); gtk_widget_show(search_window); } // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/search_playlist.h0000644000175000001440000000203410612341733015237 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: search_playlist.h 524 2007-01-06 15:39:18Z pasp $ */ #ifndef _SEARCH_PLAYLIST_H #define _SEARCH_PLAYLIST_H void search_playlist_dialog(void); #endif /* _SEARCH_PLAYLIST_H */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/search_playlist.c0000644000175000001440000003422410734552344015247 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: search_playlist.c 962 2007-12-26 19:59:09Z peterszilagyi $ */ #include #include #include #include #include #include #include "common.h" #include "utils_gui.h" #include "playlist.h" #include "gui_main.h" #include "options.h" #include "i18n.h" enum { SEARCH_F_CS = (1 << 0), /* case sensitive */ SEARCH_F_EM = (1 << 1), /* exact matches only */ SEARCH_F_SF = (1 << 2) /* select first and close */ }; extern options_t options; extern GtkWidget * playlist_window; extern GtkWidget * main_window; extern GList * playlists; static GtkWidget * search_window = NULL; static GtkWidget * searchkey_entry; static GtkWidget * check_case; static GtkWidget * check_exact; static GtkWidget * check_sfac; static GtkWidget * sres_list; static GtkListStore * search_store; static GtkTreeSelection * search_select; static int casesens; static int exactonly; static int selectfc; static void get_toggle_buttons_state(void) { casesens = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check_case)) ? 1 : 0; exactonly = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check_exact)) ? 1 : 0; selectfc = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check_sfac)) ? 1 : 0; } static void clear_search_store(void) { int i; GtkTreeIter iter; i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(search_store), &iter, NULL, i++)) { gpointer gptr; GtkTreePath * path; gtk_tree_model_get(GTK_TREE_MODEL(search_store), &iter, 1, &gptr, -1); path = (GtkTreePath *)gptr; if (path != NULL) { gtk_tree_path_free(path); } } gtk_list_store_clear(search_store); } static gint close_button_clicked(GtkWidget * widget, gpointer data) { get_toggle_buttons_state(); options.search_pl_flags = (casesens * SEARCH_F_CS) | (exactonly * SEARCH_F_EM) | (selectfc * SEARCH_F_SF); clear_search_store(); gtk_widget_destroy(search_window); search_window = NULL; return TRUE; } static int search_window_close(GtkWidget * widget, gpointer * data) { get_toggle_buttons_state(); options.search_pl_flags = (casesens * SEARCH_F_CS) | (exactonly * SEARCH_F_EM) | (selectfc * SEARCH_F_SF); clear_search_store(); search_window = NULL; return 0; } static gint sfac_clicked(GtkWidget * widget, gpointer data) { get_toggle_buttons_state(); if (selectfc) { gtk_widget_hide(sres_list); gtk_window_resize(GTK_WINDOW(search_window), 420, 138); } else { gtk_window_resize(GTK_WINDOW(search_window), 420, 355); gtk_widget_show(sres_list); } return TRUE; } void search_foreach(playlist_t * pl, GPatternSpec * pattern, GtkTreeIter * list_iter, int album_node) { char text[MAXLEN]; char * tmp = NULL; playlist_data_t * pldata; gtk_tree_model_get(GTK_TREE_MODEL(pl->store), list_iter, PL_COL_DATA, &pldata, -1); if (album_node) { snprintf(text, MAXLEN-1, "%s: %s", pldata->artist, pldata->album); } else { playlist_data_get_display_name(text, pldata); } if (casesens) { tmp = strdup(text); } else { tmp = g_utf8_strup(text, -1); } if (g_pattern_match_string(pattern, tmp)) { GtkTreeIter iter; GtkTreePath * path; path = gtk_tree_model_get_path(GTK_TREE_MODEL(pl->store), list_iter); gtk_list_store_append(search_store, &iter); gtk_list_store_set(search_store, &iter, 0, text, 1, (gpointer)path, 2, pl->name, 3, (gpointer)pl, -1); } g_free(tmp); } static gint search_button_clicked(GtkWidget * widget, gpointer data) { int valid; const char * key_string = gtk_entry_get_text(GTK_ENTRY(searchkey_entry)); char key[MAXLEN]; GPatternSpec * pattern; int i; GtkTreeIter list_iter; GtkTreeIter sfac_iter; GList * node = NULL; get_toggle_buttons_state(); clear_search_store(); valid = 0; for (i = 0; key_string[i] != '\0'; i++) { if ((key_string[i] != '?') && (key_string[i] != '*')) { valid = 1; break; } } if (!valid) { return TRUE; } if (!casesens) { key_string = g_utf8_strup(key_string, -1); } if (exactonly) { strcpy(key, key_string); } else { snprintf(key, MAXLEN-1, "*%s*", key_string); } pattern = g_pattern_spec_new(key); for (node = playlists; node; node = node->next) { playlist_t * pl = (playlist_t *)node->data; i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(pl->store), &list_iter, NULL, i++)) { if (gtk_tree_model_iter_has_child(GTK_TREE_MODEL(pl->store), &list_iter)) { int j = 0; GtkTreeIter iter; search_foreach(pl, pattern, &list_iter, 1/*album node*/); while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(pl->store), &iter, &list_iter, j++)) { search_foreach(pl, pattern, &iter, 0/*track node*/); } } else { search_foreach(pl, pattern, &list_iter, 0/*track node*/); } } } g_pattern_spec_free(pattern); if (selectfc) { if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(search_store), &sfac_iter) == TRUE) gtk_tree_selection_select_iter(search_select, &sfac_iter); close_button_clicked(NULL, NULL); } return TRUE; } static void search_selection_changed(GtkTreeSelection * treeselection, gpointer user_data) { GtkTreeIter iter; GtkTreePath * path; GtkTreePath * path_up; gpointer gptr1; gpointer gptr2; playlist_t * pl; if (!gtk_tree_selection_get_selected(search_select, NULL, &iter)) { return; } gtk_tree_model_get(GTK_TREE_MODEL(search_store), &iter, 1, &gptr1, 3, &gptr2, -1); path = (GtkTreePath *)gptr1; path_up = gtk_tree_path_copy(path); pl = (playlist_t *)gptr2; if (gtk_tree_path_up(path_up)) { gtk_tree_view_expand_row(GTK_TREE_VIEW(pl->view), path_up, FALSE); } gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(pl->view), path, NULL, TRUE, 0.5f, 0.5f); gtk_tree_view_set_cursor(GTK_TREE_VIEW(pl->view), path, NULL, FALSE); playlist_set_current(pl); gtk_tree_path_free(path_up); } static gint search_window_key_pressed(GtkWidget * widget, GdkEventKey * kevent) { switch (kevent->keyval) { case GDK_Escape: close_button_clicked(NULL, NULL); return TRUE; break; case GDK_Return: case GDK_KP_Enter: search_button_clicked(NULL, NULL); return TRUE; break; } return FALSE; } void search_playlist_dialog(void) { GtkWidget * vbox; GtkWidget * hbox; GtkWidget * label; GtkWidget * button; GtkWidget * table; GtkWidget * hbuttonbox; GtkWidget * search_viewport; GtkWidget * search_scrwin; GtkWidget * search_list; GtkCellRenderer * search_renderer; GtkTreeViewColumn * search_column; if (search_window != NULL) { return; } search_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(search_window), _("Search the Playlist")); gtk_window_set_position(GTK_WINDOW(search_window), GTK_WIN_POS_CENTER_ON_PARENT); if (options.playlist_is_embedded) { gtk_window_set_transient_for(GTK_WINDOW(search_window), GTK_WINDOW(main_window)); } else { gtk_window_set_transient_for(GTK_WINDOW(search_window), GTK_WINDOW(playlist_window)); } gtk_window_set_modal(GTK_WINDOW(search_window), TRUE); g_signal_connect(G_OBJECT(search_window), "delete_event", G_CALLBACK(search_window_close), NULL); g_signal_connect(G_OBJECT(search_window), "key_press_event", G_CALLBACK(search_window_key_pressed), NULL); gtk_container_set_border_width(GTK_CONTAINER(search_window), 5); vbox = gtk_vbox_new(FALSE, 0); gtk_widget_show(vbox); gtk_container_add(GTK_CONTAINER(search_window), vbox); hbox = gtk_hbox_new(FALSE, 0); gtk_widget_show(hbox); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 3); label = gtk_label_new(_("Key: ")); gtk_widget_show(label); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5); searchkey_entry = gtk_entry_new(); gtk_widget_show(searchkey_entry); gtk_box_pack_start(GTK_BOX(hbox), searchkey_entry, TRUE, TRUE, 5); table = gtk_table_new(4, 2, FALSE); gtk_widget_show(table); gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, TRUE, 3); check_case = gtk_check_button_new_with_label(_("Case sensitive")); gtk_widget_show(check_case); gtk_widget_set_name(check_case, "check_on_window"); gtk_table_attach(GTK_TABLE(table), check_case, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 1, 4); check_exact = gtk_check_button_new_with_label(_("Exact matches only")); gtk_widget_show(check_exact); gtk_widget_set_name(check_exact, "check_on_window"); gtk_table_attach(GTK_TABLE(table), check_exact, 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 1, 4); check_sfac = gtk_check_button_new_with_label(_("Select first and close window")); gtk_widget_show(check_sfac); gtk_widget_set_name(check_sfac, "check_on_window"); g_signal_connect(G_OBJECT(check_sfac), "clicked", G_CALLBACK(sfac_clicked), NULL); gtk_table_attach(GTK_TABLE(table), check_sfac, 0, 1, 1, 2, GTK_EXPAND | GTK_FILL, GTK_FILL, 1, 4); hbox = sres_list = gtk_hbox_new(FALSE, 0); gtk_widget_show(hbox); gtk_container_set_border_width(GTK_CONTAINER(hbox), 3); gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 3); search_viewport = gtk_viewport_new(NULL, NULL); gtk_widget_show(search_viewport); gtk_box_pack_start(GTK_BOX(hbox), search_viewport, TRUE, TRUE, 0); search_scrwin = gtk_scrolled_window_new(NULL, NULL); gtk_widget_show(search_scrwin); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(search_scrwin), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_container_add(GTK_CONTAINER(search_viewport), search_scrwin); search_store = gtk_list_store_new(4, G_TYPE_STRING, /* title */ G_TYPE_POINTER, /* GtkTreePath */ G_TYPE_STRING, /* playlist name */ G_TYPE_POINTER); /* playlist_t pointer */ gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(search_store), 0, GTK_SORT_ASCENDING); search_list = gtk_tree_view_new_with_model(GTK_TREE_MODEL(search_store)); gtk_widget_show(search_list); gtk_widget_set_size_request(search_list, 400, 200); gtk_container_add(GTK_CONTAINER(search_scrwin), search_list); search_select = gtk_tree_view_get_selection(GTK_TREE_VIEW(search_list)); gtk_tree_selection_set_mode(search_select, GTK_SELECTION_SINGLE); g_signal_connect(G_OBJECT(search_select), "changed", G_CALLBACK(search_selection_changed), NULL); search_renderer = gtk_cell_renderer_text_new(); search_column = gtk_tree_view_column_new_with_attributes(_("Playlist"), search_renderer, "text", 2, NULL); gtk_tree_view_column_set_sizing(GTK_TREE_VIEW_COLUMN(search_column), GTK_TREE_VIEW_COLUMN_AUTOSIZE); gtk_tree_view_column_set_resizable(GTK_TREE_VIEW_COLUMN(search_column), TRUE); gtk_tree_view_column_set_sort_column_id(GTK_TREE_VIEW_COLUMN(search_column), 2); gtk_tree_view_append_column(GTK_TREE_VIEW(search_list), search_column); search_renderer = gtk_cell_renderer_text_new(); search_column = gtk_tree_view_column_new_with_attributes(_("Title"), search_renderer, "text", 0, NULL); gtk_tree_view_column_set_sizing(GTK_TREE_VIEW_COLUMN(search_column), GTK_TREE_VIEW_COLUMN_AUTOSIZE); gtk_tree_view_column_set_resizable(GTK_TREE_VIEW_COLUMN(search_column), TRUE); gtk_tree_view_column_set_sort_column_id(GTK_TREE_VIEW_COLUMN(search_column), 0); gtk_tree_view_append_column(GTK_TREE_VIEW(search_list), search_column); hbuttonbox = gtk_hbutton_box_new(); gtk_widget_show (hbuttonbox); gtk_box_set_spacing(GTK_BOX(hbuttonbox), 8); gtk_box_pack_end(GTK_BOX(vbox), hbuttonbox, FALSE, TRUE, 0); gtk_button_box_set_layout(GTK_BUTTON_BOX(hbuttonbox), GTK_BUTTONBOX_END); button = gui_stock_label_button(_("Search"), GTK_STOCK_FIND); gtk_widget_show(button); gtk_container_add(GTK_CONTAINER(hbuttonbox), button); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(search_button_clicked), NULL); button = gtk_button_new_from_stock (GTK_STOCK_CLOSE); gtk_widget_show(button); gtk_container_add(GTK_CONTAINER(hbuttonbox), button); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(close_button_clicked), NULL); if (options.search_pl_flags & SEARCH_F_CS) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_case), TRUE); if (options.search_pl_flags & SEARCH_F_EM) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_exact), TRUE); if (options.search_pl_flags & SEARCH_F_SF) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_sfac), TRUE); gtk_widget_show(search_window); } // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/segv.h0000644000175000001440000000054610661105504013021 00000000000000/* -*- linux-c -*- */ /* Taken from * http://tlug.up.ac.za/wiki/index.php/Obtaining_a_stack_trace_in_C_upon_SIGSEGV * and tailored to Aqualung. */ /* $Id: segv.h 777 2007-08-16 17:34:02Z tszilagyi $ */ #ifndef _SEGV_H #define _SEGV_H #include int setup_sigsegv(); #endif /* _SEGV_H */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/segv.c0000644000175000001440000001122311243310700012777 00000000000000/* -*- linux-c -*- */ /* Taken from * http://tlug.up.ac.za/wiki/index.php/Obtaining_a_stack_trace_in_C_upon_SIGSEGV * and tailored to Aqualung. */ /* $Id: segv.c 1067 2009-07-24 09:35:15Z peterszilagyi $ */ #include #include #include #include #include #include #ifdef DEBUG_BUILD #include #include #include #include "version.h" #endif /* DEBUG_BUILD */ #include "segv.h" #ifdef DEBUG_BUILD #if defined(REG_RIP) # define SIGSEGV_STACK_IA64 # define REGFORMAT "%016lx" #elif defined(REG_EIP) # define SIGSEGV_STACK_X86 # define REGFORMAT "%08x" #else # define SIGSEGV_STACK_GENERIC # define REGFORMAT "%x" #endif #if defined(__ppc__) || defined(__powerpc__) #define UC_MCONTEXT_GREGS uc_mcontext.uc_regs->gregs #else #define UC_MCONTEXT_GREGS uc_mcontext.gregs #endif static void signal_segv(int signum, siginfo_t * info, void * ptr) { static const char *si_codes[3] = {"", "SEGV_MAPERR", "SEGV_ACCERR"}; unsigned i; ucontext_t *ucontext = (ucontext_t*)ptr; #if defined(SIGSEGV_STACK_X86) || defined(SIGSEGV_STACK_IA64) int f = 0; Dl_info dlinfo; void **bp = 0; void *ip = 0; #else void *bt[20]; char **strings; size_t sz; #endif fprintf(stderr, "===[ CRASH REPORT ]======\n"); fprintf(stderr, "Please mail this to \n"); fprintf(stderr, "along with a short description of what you were doing when\n"); fprintf(stderr, "the program crashed. Please also send the output of `aqualung -v'.\n"); fprintf(stderr, "Thank you in advance!\n\n"); fprintf(stderr, " Aqualung %s\n\n", AQUALUNG_VERSION); fprintf(stderr, " si_signo = %d (%s)\n", signum, strsignal(signum)); fprintf(stderr, " si_errno = %d\n", info->si_errno); fprintf(stderr, " si_code = %d (%s)\n", info->si_code, si_codes[info->si_code]); fprintf(stderr, " si_addr = %p\n\n", info->si_addr); for (i = 0; i < NGREG; i++) { fprintf(stderr, " R[%02u] = 0x" REGFORMAT, i, ucontext->UC_MCONTEXT_GREGS[i]); if ((i % 4) == 3) { fprintf(stderr, "\n"); } } fprintf(stderr, "\n\n"); #if defined(SIGSEGV_STACK_X86) || defined(SIGSEGV_STACK_IA64) # if defined(SIGSEGV_STACK_IA64) ip = (void*)ucontext->uc_mcontext.gregs[REG_RIP]; bp = (void**)ucontext->uc_mcontext.gregs[REG_RBP]; # elif defined(SIGSEGV_STACK_X86) ip = (void*)ucontext->uc_mcontext.gregs[REG_EIP]; bp = (void**)ucontext->uc_mcontext.gregs[REG_EBP]; # endif while (bp && ip) { if (!dladdr(ip, &dlinfo)) break; const char *symname = dlinfo.dli_sname; fprintf(stderr, "%3d: %12p <%s + %u> (%s)\n", ++f, ip, symname, (unsigned)(ip - dlinfo.dli_saddr), dlinfo.dli_fname); if(dlinfo.dli_sname && !strcmp(dlinfo.dli_sname, "main")) break; ip = bp[1]; bp = (void**)bp[0]; } #else fprintf(stderr, " backtrace():\n"); sz = backtrace(bt, 20); strings = backtrace_symbols(bt, sz); for(i = 0; i < sz; ++i) fprintf(stderr, "%s\n", strings[i]); #endif fprintf(stderr, "===[ END OF CRASH REPORT ]======\n"); exit (-1); } #endif /* DEBUG_BUILD */ #ifdef RELEASE_BUILD static void signal_segv(int signum, siginfo_t * info, void * ptr) { fprintf(stderr, "Aqualung received signal %d (%s).\n\n", signum, strsignal(signum)); #if defined(_WIN32) || defined (__FreeBSD__) || defined (__OpenBSD__) fprintf(stderr, "If you were running on Linux, you could help the\n"); fprintf(stderr, "developers by sending them the backtrace you'd get\n"); fprintf(stderr, "instead of this message...\n"); #else fprintf(stderr, "To help the developers fix the bug causing this crash,\n"); fprintf(stderr, "please do the following:\n\n"); fprintf(stderr, "1) configure & make Aqualung with --enable-debug\n"); fprintf(stderr, "2) reproduce the crash\n"); fprintf(stderr, "3) send the crash report to the developers\n\n"); fprintf(stderr, "Thank you for supporting Aqualung!\n"); #endif /* _WIN32 || __FreeBSD__ || __OpenBSD__ */ exit(-1); } #endif /* RELEASE_BUILD */ int setup_sigsegv() { struct sigaction action; memset(&action, 0, sizeof(action)); action.sa_sigaction = signal_segv; action.sa_flags = SA_SIGINFO; if (sigaction(SIGFPE, &action, NULL) < 0) { perror("sigaction"); return 0; } if (sigaction(SIGILL, &action, NULL) < 0) { perror("sigaction"); return 0; } if (sigaction(SIGSEGV, &action, NULL) < 0) { perror("sigaction"); return 0; } if (sigaction(SIGBUS, &action, NULL) < 0) { perror("sigaction"); return 0; } if (sigaction(SIGABRT, &action, NULL) < 0) { perror("sigaction"); return 0; } return 1; } #ifndef SIGSEGV_NO_AUTO_INIT static void __attribute((constructor)) init(void) { setup_sigsegv(); } #endif // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/skin.h0000644000175000001440000000202110657352325013021 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: skin.h 764 2007-08-11 09:41:50Z peterszilagyi $ */ #ifndef _SKIN_H #define _SKIN_H void create_skin_window(void); void apply_skin(char * path); #endif /* _SKIN_H */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/skin.c0000644000175000001440000001765411315737506013036 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: skin.c 1086 2009-12-27 15:25:09Z peterszilagyi $ */ #include #include #include #include #include #include #include #include #include "common.h" #include "utils_gui.h" #include "gui_main.h" #include "playlist.h" #include "options.h" #include "i18n.h" #include "skin.h" extern options_t options; extern GtkWidget * main_window; char * pdir; GtkWidget * skin_window; GtkListStore * skin_store; GtkTreeSelection * skin_select; void apply_skin_foreach(GtkWidget * window) { gtk_widget_reset_rc_styles(window); gtk_widget_queue_draw(window); } void apply_skin(char * path) { char rcpath[MAXLEN]; sprintf(rcpath, "%s/rc", path); gtk_rc_parse(rcpath); toplevel_window_foreach(TOP_WIN_SKIN, apply_skin_foreach); main_buttons_set_content(path); playlist_set_color(); } static int filter(const struct dirent * de) { struct stat st_file; char dirname[MAXLEN]; if (de->d_name[0] == '.') { return 0; } snprintf(dirname, MAXLEN-1, "%s/%s", pdir, de->d_name); if (stat(dirname, &st_file) == -1) { fprintf(stderr, "error %s: skin.c/filter(): stat() failed on %s [likely cause: nonexistent file]\n", strerror(errno), dirname); return 0; } return S_ISDIR(st_file.st_mode); } static gint cancel(GtkWidget * widget, gpointer data) { gtk_widget_destroy(skin_window); return TRUE; } static gint apply(GtkWidget * widget, gpointer data) { GtkTreeModel * model; GtkTreeIter iter; char * str; if (gtk_tree_selection_get_selected(skin_select, &model, &iter)) { gtk_tree_model_get(model, &iter, 1, &str, -1); strcpy(options.skin, str); g_free(str); gtk_widget_destroy(skin_window); apply_skin(options.skin); } return TRUE; } static gint skin_window_key_pressed(GtkWidget * widget, GdkEventKey * kevent) { switch (kevent->keyval) { case GDK_q: case GDK_Q: case GDK_Escape: cancel(NULL, NULL); return TRUE; break; case GDK_Return: case GDK_KP_Enter: apply(NULL, NULL); return TRUE; break; } return FALSE; } static gint skin_list_double_click(GtkWidget * widget, GdkEventButton * event, gpointer func_data) { if ((event->type == GDK_2BUTTON_PRESS) && (event->button == 1)) { apply(NULL, NULL); return TRUE; } return FALSE; } void create_skin_window() { GtkWidget * vbox; GtkWidget * viewp; GtkWidget * scrolledwin; GtkWidget * skin_list; GtkTreeIter iter; GtkTreeViewColumn *column; GtkCellRenderer * renderer; GtkWidget * hbuttonbox; GtkWidget * apply_btn; GtkWidget * cancel_btn; struct dirent ** ent; int n; skin_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_transient_for(GTK_WINDOW(skin_window), GTK_WINDOW(main_window)); gtk_widget_set_size_request(skin_window, 250, 240); gtk_window_set_title(GTK_WINDOW(skin_window), _("Skin chooser")); gtk_window_set_position(GTK_WINDOW(skin_window), GTK_WIN_POS_CENTER); gtk_window_set_modal(GTK_WINDOW(skin_window), TRUE); gtk_container_set_border_width(GTK_CONTAINER(skin_window), 2); g_signal_connect(G_OBJECT(skin_window), "key_press_event", G_CALLBACK(skin_window_key_pressed), NULL); vbox = gtk_vbox_new(FALSE, 0); gtk_container_add(GTK_CONTAINER(skin_window), vbox); viewp = gtk_viewport_new(NULL, NULL); gtk_box_pack_start(GTK_BOX(vbox), viewp, TRUE, TRUE, 0); scrolledwin = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwin), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); gtk_container_add(GTK_CONTAINER(viewp), scrolledwin); skin_store = gtk_list_store_new(2, G_TYPE_STRING, /* skin name */ G_TYPE_STRING); /* path */ skin_list = gtk_tree_view_new_with_model(GTK_TREE_MODEL(skin_store)); gtk_tree_view_set_enable_search(GTK_TREE_VIEW(skin_list), FALSE); g_signal_connect(G_OBJECT(skin_list), "button_press_event", G_CALLBACK(skin_list_double_click), NULL); skin_select = gtk_tree_view_get_selection(GTK_TREE_VIEW(skin_list)); renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes(_("Available skins"), renderer, "text", 0, NULL); gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(skin_store), 0, GTK_SORT_ASCENDING); gtk_tree_view_append_column(GTK_TREE_VIEW(skin_list), column); gtk_container_add(GTK_CONTAINER(scrolledwin), skin_list); /* per-user skins */ pdir = options.confdir; n = scandir(options.confdir, &ent, filter, alphasort); if (n >= 0) { int c; char path[MAXLEN]; for (c = 0; c < n; ++c) { gtk_list_store_append(skin_store, &iter); snprintf(path, MAXLEN - 1, "%s/%s", options.confdir, ent[c]->d_name); gtk_list_store_set(skin_store, &iter, 0, ent[c]->d_name, 1, path, -1); free(ent[c]); } free(ent); } /* system wide skins */ pdir = AQUALUNG_SKINDIR; n = scandir(AQUALUNG_SKINDIR, &ent, filter, alphasort); if (n >= 0) { int c; char path[MAXLEN]; for (c = 0; c < n; ++c) { int found = 0; if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(skin_store), &iter)) { int i = 0; char * str; do { gtk_tree_model_get(GTK_TREE_MODEL(skin_store), &iter, 0, &str, -1); if (strcmp(str, ent[c]->d_name) == 0) { found = 1; } g_free(str); } while (i++, gtk_tree_model_iter_next(GTK_TREE_MODEL(skin_store), &iter)); } if (!found) { if (strncmp(ent[c]->d_name, "no_skin", MAXLEN-1)) { gtk_list_store_append(skin_store, &iter); snprintf(path, MAXLEN - 1, "%s/%s", AQUALUNG_SKINDIR, ent[c]->d_name); gtk_list_store_set(skin_store, &iter, 0, ent[c]->d_name, 1, path, -1); } } free(ent[c]); } free(ent); } hbuttonbox = gtk_hbutton_box_new(); gtk_box_pack_end(GTK_BOX(vbox), hbuttonbox, FALSE, TRUE, 0); gtk_button_box_set_layout(GTK_BUTTON_BOX(hbuttonbox), GTK_BUTTONBOX_END); gtk_box_set_spacing(GTK_BOX(hbuttonbox), 8); gtk_container_set_border_width(GTK_CONTAINER(hbuttonbox), 3); apply_btn = gtk_button_new_from_stock (GTK_STOCK_APPLY); g_signal_connect(apply_btn, "clicked", G_CALLBACK(apply), NULL); gtk_container_add(GTK_CONTAINER(hbuttonbox), apply_btn); cancel_btn = gtk_button_new_from_stock (GTK_STOCK_CANCEL); g_signal_connect(cancel_btn, "clicked", G_CALLBACK(cancel), NULL); gtk_container_add(GTK_CONTAINER(hbuttonbox), cancel_btn); gtk_widget_show_all(skin_window); if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(skin_store), &iter)) { int i = 0; char * str; do { gtk_tree_model_get(GTK_TREE_MODEL(skin_store), &iter, 1, &str, -1); if (strcmp(str, options.skin) == 0) { gtk_tree_selection_select_iter(skin_select, &iter); gtk_tree_view_set_cursor(GTK_TREE_VIEW(skin_list), gtk_tree_model_get_path(GTK_TREE_MODEL(skin_store), &iter), NULL, FALSE); } g_free(str); } while (i++, gtk_tree_model_iter_next(GTK_TREE_MODEL(skin_store), &iter)); } } // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/store_cdda.h0000644000175000001440000000357110731047243014170 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: store_cdda.h 925 2007-12-13 21:20:41Z peterszilagyi $ */ #ifndef _STORE_CDDA_H #define _STORE_CDDA_H #include #ifdef HAVE_CDDA #include #include "cdda.h" void create_cdda_node(void); int store_cdda_iter_is_track(GtkTreeIter * iter); void store_cdda_iter_addlist_defmode(GtkTreeIter * ms_iter, GtkTreeIter * pl_iter, int new_tab); void store_cdda_selection_changed(GtkTreeIter * iter, GtkTextBuffer * buffer, GtkLabel * statusbar); gboolean store_cdda_event_cb(GdkEvent * event, GtkTreeIter * iter, GtkTreePath * path); void store_cdda_load_icons(void); void store_cdda_create_popup_menu(void); gboolean store_cdda_remove_track(GtkTreeIter * iter); gboolean store_cdda_remove_record(GtkTreeIter * iter); void cdda_record_auto_query_cddb(GtkTreeIter * drive_iter); void cdda_add_to_playlist(GtkTreeIter * iter_drive, unsigned long hash); void cdda_remove_from_playlist(cdda_drive_t * drive); typedef struct { char * path; float duration; } cdda_track_t; #endif /* HAVE_CDDA */ #endif /* _STORE_CDDA_H */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/store_cdda.c0000644000175000001440000011531710734700601014162 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: store_cdda.c 964 2007-12-27 09:57:28Z peterszilagyi $ */ #include #ifdef HAVE_CDDA #include #include #include #include #include #ifndef _WIN32 #include #endif /* !_WIN32 */ #ifdef HAVE_CDDB #define _TMP_HAVE_CDDB 1 #undef HAVE_CDDB #endif /* HAVE_CDDB */ #include #include #include #ifdef HAVE_CDDB #undef HAVE_CDDB #endif /* HAVE_CDDB */ #ifdef _TMP_HAVE_CDDB #define HAVE_CDDB 1 #undef _TMP_HAVE_CDDB #endif /* _TMP_HAVE_CDDB */ #include "common.h" #include "utils.h" #include "utils_gui.h" #include "options.h" #include "music_browser.h" #include "cddb_lookup.h" #include "playlist.h" #include "i18n.h" #include "cdda.h" #include "cd_ripper.h" #include "store_cdda.h" extern GtkTreeSelection * music_select; extern char pl_color_inactive[14]; extern options_t options; extern GdkPixbuf * icon_store; extern GdkPixbuf * icon_record; extern GdkPixbuf * icon_track; extern GtkTreeStore * music_store; extern GtkWidget * browser_window; extern GList * playlists; GtkWidget * cdda_track_menu; GtkWidget * cdda_track__addlist; GtkWidget * cdda_record_menu; GtkWidget * cdda_record__addlist; GtkWidget * cdda_record__addlist_albummode; GtkWidget * cdda_record__separator1; #ifdef HAVE_CDDB GtkWidget * cdda_record__cddb; GtkWidget * cdda_record__cddb_submit; #endif /* HAVE_CDDB */ #ifdef HAVE_CD_RIPPER GtkWidget * cdda_record__rip; #endif /* HAVE_CD_RIPPER */ GtkWidget * cdda_record__disc_info; GtkWidget * cdda_record__eject; GtkWidget * cdda_record__separator2; GtkWidget * cdda_record__drive_info; GtkWidget * cdda_store_menu; GtkWidget * cdda_store__addlist; GtkWidget * cdda_store__addlist_albummode; GdkPixbuf * icon_cdda; GdkPixbuf * icon_cdda_disc; GdkPixbuf * icon_cdda_nodisc; void cdda_store__addlist_defmode(gpointer data); void cdda_record__addlist_defmode(gpointer data); void cdda_track__addlist_cb(gpointer data); struct keybinds cdda_store_keybinds[] = { {cdda_store__addlist_defmode, GDK_a, GDK_A, 0}, {NULL, 0, 0} }; struct keybinds cdda_record_keybinds[] = { {cdda_record__addlist_defmode, GDK_a, GDK_A, 0}, {NULL, 0, 0} }; struct keybinds cdda_track_keybinds[] = { {cdda_track__addlist_cb, GDK_a, GDK_A, 0}, {NULL, 0, 0} }; void cdda_track_free(cdda_track_t * data) { free(data->path); free(data); } gboolean store_cdda_remove_track(GtkTreeIter * iter) { cdda_track_t * data; gtk_tree_model_get(GTK_TREE_MODEL(music_store), iter, MS_COL_DATA, &data, -1); cdda_track_free(data); return gtk_tree_store_remove(music_store, iter); } gboolean store_cdda_remove_record(GtkTreeIter * iter) { GtkTreeIter track_iter; int i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &track_iter, iter, i++)) { store_cdda_remove_track(&track_iter); } return gtk_tree_store_remove(music_store, iter); } void cdda_info_row(char * text, int yes, GtkWidget * table, int * cnt) { GtkWidget * image; GtkWidget * label; GtkWidget * hbox; image = gtk_image_new_from_stock(yes ? GTK_STOCK_APPLY : GTK_STOCK_CANCEL, GTK_ICON_SIZE_BUTTON); label = gtk_label_new(text); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(table), image, 0, 1, *cnt, *cnt+1, GTK_FILL, GTK_FILL, 2, 1); gtk_table_attach(GTK_TABLE(table), hbox, 1, 2, *cnt, *cnt+1, GTK_FILL, GTK_FILL, 5, 1); (*cnt)++; } void cdda_drive_info(cdda_drive_t * drive) { CdIo_t * cdio; cdio_hwinfo_t hwinfo; cdio_drive_read_cap_t read_cap; cdio_drive_write_cap_t write_cap; cdio_drive_misc_cap_t misc_cap; GtkWidget * dialog; GtkWidget * label; GtkWidget * hbox; GtkWidget * vbox; GtkWidget * notebook; GtkWidget * table; char str[MAXLEN]; cdio = cdio_open(drive->device_path, DRIVER_UNKNOWN); if (!cdio_get_hwinfo(cdio, &hwinfo)) { cdio_destroy(cdio); return; } cdio_get_drive_cap(cdio, &read_cap, &write_cap, &misc_cap); cdio_destroy(cdio); snprintf(str, MAXLEN-1, "%s [%s]", _("Drive info"), cdda_displayed_device_path(drive->device_path)); dialog = gtk_dialog_new_with_buttons(str, GTK_WINDOW(browser_window), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR, GTK_STOCK_CLOSE, GTK_RESPONSE_OK, NULL); gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER); vbox = gtk_vbox_new(FALSE, 0); gtk_container_set_border_width(GTK_CONTAINER(vbox), 5); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), vbox, FALSE, FALSE, 4); table = gtk_table_new(4, 2, FALSE); gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 2); hbox = gtk_hbox_new(FALSE, 0); label = gtk_label_new(_("Device path:")); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(table), hbox, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 4, 1); hbox = gtk_hbox_new(FALSE, 0); label = gtk_label_new(cdda_displayed_device_path(drive->device_path)); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(table), hbox, 1, 2, 0, 1, GTK_FILL, GTK_FILL, 4, 1); hbox = gtk_hbox_new(FALSE, 0); label = gtk_label_new(_("Vendor:")); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(table), hbox, 0, 1, 1, 2, GTK_FILL, GTK_FILL, 4, 1); hbox = gtk_hbox_new(FALSE, 0); label = gtk_label_new(hwinfo.psz_vendor); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(table), hbox, 1, 2, 1, 2, GTK_FILL, GTK_FILL, 4, 1); hbox = gtk_hbox_new(FALSE, 0); label = gtk_label_new(_("Model:")); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(table), hbox, 0, 1, 2, 3, GTK_FILL, GTK_FILL, 4, 1); hbox = gtk_hbox_new(FALSE, 0); label = gtk_label_new(hwinfo.psz_model); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(table), hbox, 1, 2, 2, 3, GTK_FILL, GTK_FILL, 4, 1); hbox = gtk_hbox_new(FALSE, 0); label = gtk_label_new(_("Revision:")); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(table), hbox, 0, 1, 3, 4, GTK_FILL, GTK_FILL, 4, 1); hbox = gtk_hbox_new(FALSE, 0); label = gtk_label_new(hwinfo.psz_revision); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(table), hbox, 1, 2, 3, 4, GTK_FILL, GTK_FILL, 4, 1); hbox = gtk_hbox_new(FALSE, 0); label = gtk_label_new(_("The information below is reported by the drive, and\n" "may not reflect the actual capabilities of the device.")); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 3); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 10); if ((misc_cap == CDIO_DRIVE_CAP_ERROR) && (read_cap == CDIO_DRIVE_CAP_ERROR) && (write_cap == CDIO_DRIVE_CAP_ERROR)) { goto cdda_info_finish; } notebook = gtk_notebook_new(); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), notebook, TRUE, TRUE, 0); if (misc_cap != CDIO_DRIVE_CAP_ERROR) { int cnt = 0; label = gtk_label_new(_("General")); table = gtk_table_new(8, 2, FALSE); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), table, label); cdda_info_row(_("Eject"), misc_cap & CDIO_DRIVE_CAP_MISC_EJECT, table, &cnt); cdda_info_row(_("Close tray"), misc_cap & CDIO_DRIVE_CAP_MISC_CLOSE_TRAY, table, &cnt); cdda_info_row(_("Disable manual eject"), misc_cap & CDIO_DRIVE_CAP_MISC_LOCK, table, &cnt); cdda_info_row(_("Select juke-box disc"), misc_cap & CDIO_DRIVE_CAP_MISC_SELECT_DISC, table, &cnt); cdda_info_row(_("Set drive speed"), misc_cap & CDIO_DRIVE_CAP_MISC_SELECT_SPEED, table, &cnt); cdda_info_row(_("Detect media change"), misc_cap & CDIO_DRIVE_CAP_MISC_MEDIA_CHANGED, table, &cnt); cdda_info_row(_("Read multiple sessions"), misc_cap & CDIO_DRIVE_CAP_MISC_MULTI_SESSION, table, &cnt); cdda_info_row(_("Hard reset device"), misc_cap & CDIO_DRIVE_CAP_MISC_RESET, table, &cnt); } if (read_cap != CDIO_DRIVE_CAP_ERROR) { int cnt = 0; label = gtk_label_new(_("Reading")); table = gtk_table_new(16, 2, FALSE); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), table, label); cdda_info_row(_("Play CD Audio"), read_cap & CDIO_DRIVE_CAP_READ_AUDIO, table, &cnt); cdda_info_row(_("Read CD-DA"), read_cap & CDIO_DRIVE_CAP_READ_CD_DA, table, &cnt); cdda_info_row(_("Read CD+G"), read_cap & CDIO_DRIVE_CAP_READ_CD_G, table, &cnt); cdda_info_row(_("Read CD-R"), read_cap & CDIO_DRIVE_CAP_READ_CD_R, table, &cnt); cdda_info_row(_("Read CD-RW"), read_cap & CDIO_DRIVE_CAP_READ_CD_RW, table, &cnt); cdda_info_row(_("Read DVD-R"), read_cap & CDIO_DRIVE_CAP_READ_DVD_R, table, &cnt); cdda_info_row(_("Read DVD+R"), read_cap & CDIO_DRIVE_CAP_READ_DVD_PR, table, &cnt); cdda_info_row(_("Read DVD-RW"), read_cap & CDIO_DRIVE_CAP_READ_DVD_RW, table, &cnt); cdda_info_row(_("Read DVD+RW"), read_cap & CDIO_DRIVE_CAP_READ_DVD_RPW, table, &cnt); cdda_info_row(_("Read DVD-RAM"), read_cap & CDIO_DRIVE_CAP_READ_DVD_RAM, table, &cnt); cdda_info_row(_("Read DVD-ROM"), read_cap & CDIO_DRIVE_CAP_READ_DVD_ROM, table, &cnt); cdda_info_row(_("C2 Error Correction"), read_cap & CDIO_DRIVE_CAP_READ_C2_ERRS, table, &cnt); cdda_info_row(_("Read Mode 2 Form 1"), read_cap & CDIO_DRIVE_CAP_READ_MODE2_FORM1, table, &cnt); cdda_info_row(_("Read Mode 2 Form 2"), read_cap & CDIO_DRIVE_CAP_READ_MODE2_FORM2, table, &cnt); cdda_info_row(_("Read MCN"), read_cap & CDIO_DRIVE_CAP_READ_MCN, table, &cnt); cdda_info_row(_("Read ISRC"), read_cap & CDIO_DRIVE_CAP_READ_ISRC, table, &cnt); } if (write_cap != CDIO_DRIVE_CAP_ERROR) { int cnt = 0; label = gtk_label_new(_("Writing")); table = gtk_table_new(9, 2, FALSE); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), table, label); cdda_info_row(_("Write CD-R"), write_cap & CDIO_DRIVE_CAP_WRITE_CD_R, table, &cnt); cdda_info_row(_("Write CD-RW"), write_cap & CDIO_DRIVE_CAP_WRITE_CD_RW, table, &cnt); cdda_info_row(_("Write DVD-R"), write_cap & CDIO_DRIVE_CAP_WRITE_DVD_R, table, &cnt); cdda_info_row(_("Write DVD+R"), write_cap & CDIO_DRIVE_CAP_WRITE_DVD_PR, table, &cnt); cdda_info_row(_("Write DVD-RW"), write_cap & CDIO_DRIVE_CAP_WRITE_DVD_RW, table, &cnt); cdda_info_row(_("Write DVD+RW"), write_cap & CDIO_DRIVE_CAP_WRITE_DVD_RPW, table, &cnt); cdda_info_row(_("Write DVD-RAM"), write_cap & CDIO_DRIVE_CAP_WRITE_DVD_RAM, table, &cnt); cdda_info_row(_("Mount Rainier"), write_cap & CDIO_DRIVE_CAP_WRITE_MT_RAINIER, table, &cnt); cdda_info_row(_("Burn Proof"), write_cap & CDIO_DRIVE_CAP_WRITE_BURN_PROOF, table, &cnt); } cdda_info_finish: gtk_widget_show_all(dialog); aqualung_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); } void cdda_disc_info(cdda_drive_t * drive) { CdIo_t * cdio; cdtext_t * cdtext; track_t itrack; track_t ntracks; track_t track_last; int i; GtkWidget * dialog; GtkWidget * table; GtkWidget * label; GtkWidget * vbox; GtkWidget * hbox; GtkListStore * list; GtkWidget * view; GtkWidget * viewport; GtkWidget * scrolled_win; GtkCellRenderer * cell; GType types[MAX_CDTEXT_FIELDS + 1]; GtkTreeViewColumn * columns[MAX_CDTEXT_FIELDS + 1]; int visible[MAX_CDTEXT_FIELDS + 1]; int has_some_cdtext = 0; dialog = gtk_dialog_new_with_buttons(_("Disc info"), GTK_WINDOW(browser_window), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR, GTK_STOCK_CLOSE, GTK_RESPONSE_OK, NULL); gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER); gtk_widget_set_size_request(GTK_WIDGET(dialog), 500, 400); vbox = gtk_vbox_new(FALSE, 0); gtk_container_set_border_width(GTK_CONTAINER(vbox), 5); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), vbox, TRUE, TRUE, 4); cdio = cdio_open(drive->device_path, DRIVER_UNKNOWN); cdtext = cdio_get_cdtext(cdio, 0); if (cdtext != NULL) { table = gtk_table_new(MAX_CDTEXT_FIELDS, 2, FALSE); gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 2); for (i = 0; i < MAX_CDTEXT_FIELDS; i++) { if (cdtext->field[i] == NULL || *(cdtext->field[i]) == '\0') { continue; } has_some_cdtext = 1; hbox = gtk_hbox_new(FALSE, 0); label = gtk_label_new(cdtext_field2str(i)); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(table), hbox, 0, 1, i, i + 1, GTK_FILL, GTK_FILL, 4, 1); hbox = gtk_hbox_new(FALSE, 0); label = gtk_label_new(cdtext->field[i]); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(table), hbox, 1, 2, i, i + 1, GTK_FILL, GTK_FILL, 4, 1); } } types[0] = G_TYPE_INT; for (i = 1; i <= MAX_CDTEXT_FIELDS; i++) { types[i] = G_TYPE_STRING; visible[i] = 0; } list = gtk_list_store_newv(MAX_CDTEXT_FIELDS + 1, types); view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(list)); viewport = gtk_viewport_new(NULL, NULL); scrolled_win = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_win), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_box_pack_start(GTK_BOX(vbox), viewport, TRUE, TRUE, 2); gtk_container_add(GTK_CONTAINER(viewport), scrolled_win); gtk_container_add(GTK_CONTAINER(scrolled_win), view); cell = gtk_cell_renderer_text_new(); g_object_set((gpointer)cell, "xalign", 1.0, NULL); columns[0] = gtk_tree_view_column_new_with_attributes(_("No."), cell, "text", 0, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(view), GTK_TREE_VIEW_COLUMN(columns[0])); for (i = 0; i < MAX_CDTEXT_FIELDS; i++) { cell = gtk_cell_renderer_text_new(); columns[i + 1] = gtk_tree_view_column_new_with_attributes(cdtext_field2str(i), cell, "text", i + 1, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(view), GTK_TREE_VIEW_COLUMN(columns[i + 1])); } itrack = cdio_get_first_track_num(cdio); ntracks = cdio_get_num_tracks(cdio); track_last = itrack + ntracks; for (; itrack < track_last; itrack++) { GtkTreeIter iter; gtk_list_store_append(list, &iter); gtk_list_store_set(list, &iter, 0, itrack, -1); cdtext = cdio_get_cdtext(cdio, itrack); if (cdtext == NULL) { continue; } for (i = 0; i < MAX_CDTEXT_FIELDS; i++) { if (cdtext->field[i] != NULL && *(cdtext->field[i]) != '\0') { gtk_list_store_set(list, &iter, i + 1, cdtext->field[i], -1); visible[i + 1] = 1; has_some_cdtext = 1; } } } for (i = 1; i <= MAX_CDTEXT_FIELDS; i++) { gtk_tree_view_column_set_visible(columns[i], visible[i]); } cdio_destroy(cdio); gtk_widget_show_all(dialog); if (has_some_cdtext) { aqualung_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); } else { gtk_widget_destroy(dialog); message_dialog(_("Disc info"), browser_window, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, NULL, _("This CD does not contain CD-Text information.")); } } void cdda_record_cb(void (* callback)(cdda_drive_t *)) { GtkTreeIter iter; GtkTreeModel * model; if (gtk_tree_selection_get_selected(music_select, &model, &iter)) { cdda_drive_t * drive; gtk_tree_model_get(model, &iter, MS_COL_DATA, &drive, -1); (*callback)(drive); } } void cdda_record__do_eject(cdda_drive_t * drive) { CdIo_t * cdio = cdio_open(drive->device_path, DRIVER_DEVICE); if (cdio) { cdio_eject_media(&cdio); if (cdio != NULL) { cdio_destroy(cdio); } } } void cdda_record__disc_cb(gpointer data) { cdda_record_cb(cdda_disc_info); } void cdda_record__drive_cb(gpointer data) { cdda_record_cb(cdda_drive_info); } void cdda_record__eject_cb(gpointer data) { cdda_record_cb(cdda_record__do_eject); } #ifdef HAVE_CD_RIPPER void cdda_record__rip_cb(gpointer data) { GtkTreeIter iter; GtkTreeModel * model; if (gtk_tree_selection_get_selected(music_select, &model, &iter)) { cdda_drive_t * drive; gtk_tree_model_get(model, &iter, MS_COL_DATA, &drive, -1); cd_ripper(drive, &iter); } } #endif /* HAVE_CD_RIPPER */ #ifdef HAVE_CDDB static int cddb_init_query_data(GtkTreeIter * iter_record, int * ntracks, int ** frames, int * length) { int i; float len = 0.0f; float offset = 150.0f; /* leading 2 secs in frames */ GtkTreeIter iter_track; cdda_track_t * data; *ntracks = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(music_store), iter_record); if ((*frames = (int *)calloc(*ntracks, sizeof(int))) == NULL) { fprintf(stderr, "store_cdda.c: cddb_init_query_data: calloc error\n"); return 1; } i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &iter_track, iter_record, i)) { gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter_track, MS_COL_DATA, &data, -1); *((*frames) + i) = (int)offset; len += data->duration; offset += 75.0f * data->duration; ++i; } *length = (int)len; return 0; } void cdda_record__cddb_cb(gpointer data) { GtkTreeIter iter; if (gtk_tree_selection_get_selected(music_select, NULL, &iter)) { int ntracks; int * frames; int length; if (cddb_init_query_data(&iter, &ntracks, &frames, &length) == 0) { cddb_start_query(&iter, ntracks, frames, length); } } } void cdda_record__cddb_submit_cb(gpointer data) { GtkTreeIter iter; if (gtk_tree_selection_get_selected(music_select, NULL, &iter)) { int ntracks; int * frames; int length; if (cddb_init_query_data(&iter, &ntracks, &frames, &length) == 0) { cddb_start_submit(&iter, ntracks, frames, length); } } } void cdda_record_auto_query_cddb(GtkTreeIter * drive_iter) { int ntracks; int * frames; int length; if (cddb_init_query_data(drive_iter, &ntracks, &frames, &length) == 0) { cddb_auto_query_cdda(drive_iter, ntracks, frames, length); } } #endif /* HAVE_CDDB */ /********************************************/ /* returns the duration of the track */ float cdda_track_addlist_iter(GtkTreeIter iter_track, playlist_t * pl, GtkTreeIter * parent, GtkTreeIter * dest) { GtkTreeIter dest_parent; GtkTreeIter iter_record; GtkTreeIter list_iter; cdda_track_t * data; cdda_drive_t * drive; char * track_name; char list_str[MAXLEN]; char duration_str[MAXLEN]; playlist_data_t * pldata = NULL; gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter_track, MS_COL_NAME, &track_name, MS_COL_DATA, &data, -1); gtk_tree_model_iter_parent(GTK_TREE_MODEL(music_store), &iter_record, &iter_track); gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter_record, MS_COL_DATA, &drive, -1); if (parent != NULL || (dest != NULL && gtk_tree_model_iter_parent(GTK_TREE_MODEL(pl->store), &dest_parent, dest))) { GtkTreeIter * piter = (parent != NULL) ? parent : &dest_parent; playlist_data_t * pdata; gtk_tree_model_get(GTK_TREE_MODEL(pl->store), piter, PL_COL_DATA, &pdata, -1); if (pdata->artist && pdata->album && !strcmp(pdata->artist, drive->disc.artist_name) && !strcmp(pdata->album, drive->disc.record_name)) { strcpy(list_str, track_name); } else { make_title_string(list_str, options.title_format, drive->disc.artist_name, drive->disc.record_name, track_name); } } else { make_title_string(list_str, options.title_format, drive->disc.artist_name, drive->disc.record_name, track_name); } time2time(data->duration, duration_str); if ((pldata = playlist_data_new()) == NULL) { return 0; } pldata->artist = strdup(drive->disc.artist_name); pldata->album = strdup(drive->disc.record_name); pldata->title = strdup(track_name); pldata->file = strdup(data->path); pldata->duration = data->duration; /* either parent or dest should be set, but not both */ gtk_tree_store_insert_before(pl->store, &list_iter, parent, dest); gtk_tree_store_set(pl->store, &list_iter, PL_COL_NAME, list_str, PL_COL_VADJ, "", PL_COL_DURA, duration_str, PL_COL_COLO, pl_color_inactive, PL_COL_FONT, PANGO_WEIGHT_NORMAL, PL_COL_DATA, pldata, -1); g_free(track_name); return data->duration; } void cdda_record_addlist_iter(GtkTreeIter iter_record, playlist_t * pl, GtkTreeIter * dest, int album_mode) { GtkTreeIter iter_track; GtkTreeIter list_iter; GtkTreeIter * plist_iter; int i; float record_duration = 0.0f; playlist_data_t * pldata = NULL; if (gtk_tree_model_iter_n_children(GTK_TREE_MODEL(music_store), &iter_record) == 0) { return; } if (album_mode) { char list_str[MAXLEN]; cdda_drive_t * drive; if ((pldata = playlist_data_new()) == NULL) { return; } gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter_record, MS_COL_DATA, &drive, -1); snprintf(list_str, MAXLEN-1, "%s: %s", drive->disc.artist_name, drive->disc.record_name); pldata->artist = strdup(drive->disc.artist_name); pldata->album = strdup(drive->disc.record_name); gtk_tree_store_insert_before(pl->store, &list_iter, NULL, dest); gtk_tree_store_set(pl->store, &list_iter, PL_COL_NAME, list_str, PL_COL_VADJ, "", PL_COL_DURA, "00:00", PL_COL_COLO, pl_color_inactive, PL_COL_FONT, PANGO_WEIGHT_NORMAL, PL_COL_DATA, pldata, -1); plist_iter = &list_iter; dest = NULL; } else { plist_iter = NULL; } i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &iter_track, &iter_record, i++)) { record_duration += cdda_track_addlist_iter(iter_track, pl, plist_iter, dest); } if (album_mode) { char duration_str[MAXLEN]; pldata->duration = record_duration; time2time(record_duration, duration_str); gtk_tree_store_set(pl->store, &list_iter, PL_COL_DURA, duration_str, -1); } } void cdda_track__addlist_cb(gpointer data) { GtkTreeIter iter_track; playlist_t * pl = playlist_get_current(); if (gtk_tree_selection_get_selected(music_select, NULL, &iter_track)) { cdda_track_addlist_iter(iter_track, pl, NULL, (GtkTreeIter *)data); if (pl == playlist_get_current()) { playlist_content_changed(pl); } } } void cdda_record__addlist_with_mode(int mode, gpointer data) { GtkTreeIter iter_record; playlist_t * pl = playlist_get_current(); if (gtk_tree_selection_get_selected(music_select, NULL, &iter_record)) { cdda_record_addlist_iter(iter_record, pl, (GtkTreeIter *)data, mode); if (pl == playlist_get_current()) { playlist_content_changed(pl); } } } void cdda_record__addlist_defmode(gpointer data) { cdda_record__addlist_with_mode(options.playlist_is_tree, data); } void cdda_record__addlist_albummode_cb(gpointer data) { cdda_record__addlist_with_mode(1, data); } void cdda_record__addlist_cb(gpointer data) { cdda_record__addlist_with_mode(0, data); } void cdda_store_addlist_iter(GtkTreeIter iter_store, playlist_t * pl, GtkTreeIter * dest, int album_mode) { GtkTreeIter iter_record; int i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &iter_record, &iter_store, i++)) { cdda_record_addlist_iter(iter_record, pl, dest, album_mode); } } void cdda_store__addlist_with_mode(int mode, gpointer data) { GtkTreeIter iter_store; playlist_t * pl = playlist_get_current(); if (gtk_tree_selection_get_selected(music_select, NULL, &iter_store)) { cdda_store_addlist_iter(iter_store, pl, (GtkTreeIter *)data, mode); if (pl == playlist_get_current()) { playlist_content_changed(pl); } } } void cdda_store__addlist_defmode(gpointer data) { cdda_store__addlist_with_mode(options.playlist_is_tree, data); } void cdda_store__addlist_albummode_cb(gpointer data) { cdda_store__addlist_with_mode(1, data); } void cdda_store__addlist_cb(gpointer data) { cdda_store__addlist_with_mode(0, data); } void cdda_add_to_playlist(GtkTreeIter * iter_drive, unsigned long hash) { int i = 0; GtkTreeIter iter; int target_found = 0; GtkTreeIter target_iter; playlist_t * pl = NULL; playlist_data_t * pldata = NULL; if ((pl = playlist_get_current()) == NULL) { printf("NULL\n"); return; } while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(pl->store), &iter, NULL, i++)) { if (gtk_tree_model_iter_n_children(GTK_TREE_MODEL(pl->store), &iter) > 0) { int j = 0; int has_cdda = 0; GtkTreeIter child; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(pl->store), &child, &iter, j++)) { gtk_tree_model_get(GTK_TREE_MODEL(pl->store), &child, PL_COL_DATA, &pldata, -1); if (!target_found && cdda_is_cdtrack(pldata->file)) { has_cdda = 1; } if (cdda_hash_matches(pldata->file, hash)) { return; } } if (!target_found && !has_cdda) { target_iter = iter; target_found = 1; } } else { gtk_tree_model_get(GTK_TREE_MODEL(pl->store), &iter, PL_COL_DATA, &pldata, -1); if (!target_found && !cdda_is_cdtrack(pldata->file)) { target_iter = iter; target_found = 1; } if (cdda_hash_matches(pldata->file, hash)) { return; } } } if (target_found) { cdda_record_addlist_iter(*iter_drive, pl, &target_iter, options.playlist_is_tree); } else { cdda_record_addlist_iter(*iter_drive, pl, NULL, options.playlist_is_tree); } playlist_content_changed(pl); } void cdda_remove_from_playlist_foreach(gpointer data, gpointer user_data) { int i = 0; GtkTreeIter iter; unsigned long hash; playlist_t * pl = (playlist_t *)data; cdda_drive_t * drive = (cdda_drive_t *)user_data; playlist_data_t * pldata = NULL; if (drive->disc.hash == 0) { hash = drive->disc.hash_prev; } else { hash = drive->disc.hash; } while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(pl->store), &iter, NULL, i++)) { if (gtk_tree_model_iter_n_children(GTK_TREE_MODEL(pl->store), &iter) > 0) { int j = 0; GtkTreeIter child; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(pl->store), &child, &iter, j++)) { gtk_tree_model_get(GTK_TREE_MODEL(pl->store), &child, PL_COL_DATA, &pldata, -1); if (cdda_hash_matches(pldata->file, hash)) { gtk_tree_store_remove(pl->store, &child); --j; } } if (gtk_tree_model_iter_n_children(GTK_TREE_MODEL(pl->store), &iter) == 0) { gtk_tree_store_remove(pl->store, &iter); --i; } else { recalc_album_node(pl, &iter); } } else { gtk_tree_model_get(GTK_TREE_MODEL(pl->store), &iter, PL_COL_DATA, &pldata, -1); if (cdda_hash_matches(pldata->file, hash)) { gtk_tree_store_remove(pl->store, &iter); --i; } } } playlist_content_changed(pl); } void cdda_remove_from_playlist(cdda_drive_t * drive) { g_list_foreach(playlists, cdda_remove_from_playlist_foreach, drive); } static void track_status_bar_info(GtkTreeModel * model, GtkTreeIter * iter, float * length) { cdda_track_t * data; gtk_tree_model_get(model, iter, MS_COL_DATA, &data, -1); *length += data->duration; } static void record_status_bar_info(GtkTreeModel * model, GtkTreeIter * iter, float * length, int * ntrack, int * nrecord) { GtkTreeIter track_iter; int i = 0; while (gtk_tree_model_iter_nth_child(model, &track_iter, iter, i++)) { track_status_bar_info(model, &track_iter, length); } *ntrack += i - 1; if (i > 1) { (*nrecord)++; } } static void store_status_bar_info(GtkTreeModel * model, GtkTreeIter * iter, float * length, int * ntrack, int * nrecord, int * ndrive) { GtkTreeIter record_iter; int i = 0; while (gtk_tree_model_iter_nth_child(model, &record_iter, iter, i++)) { record_status_bar_info(model, &record_iter, length, ntrack, nrecord); } *ndrive = i - 1; } static void set_status_bar_info(GtkTreeIter * tree_iter, GtkLabel * statusbar) { int ntrack = 0, nrecord = 0, ndrive = 0; float length = 0.0f; char str[MAXLEN]; char length_str[MAXLEN]; char tmp[MAXLEN]; char * name; GtkTreeModel * model = GTK_TREE_MODEL(music_store); GtkTreePath * path; int depth; path = gtk_tree_model_get_path(model, tree_iter); depth = gtk_tree_path_get_depth(path); gtk_tree_path_free(path); gtk_tree_model_get(model, tree_iter, MS_COL_NAME, &name, -1); switch (depth) { case 3: track_status_bar_info(model, tree_iter, &length); sprintf(str, "%s ", name); break; case 2: record_status_bar_info(model, tree_iter, &length, &ntrack, &nrecord); if (nrecord == 0) { sprintf(str, "%s: %s ", _("CD Audio"), name); } else { sprintf(str, "%s: %d %s ", name, ntrack, (ntrack == 1) ? _("track") : _("tracks")); } break; case 1: store_status_bar_info(model, tree_iter, &length, &ntrack, &nrecord, &ndrive); sprintf(str, "%s: %d %s, %d %s, %d %s ", name, ndrive, (ndrive == 1) ? _("drive") : _("drives"), nrecord, (nrecord == 1) ? _("record") : _("records"), ntrack, (ntrack == 1) ? _("track") : _("tracks")); break; } g_free(name); if (length > 0.0f) { time2time(length, length_str); sprintf(tmp, " [%s] ", length_str); strcat(str, tmp); } gtk_label_set_text(statusbar, str); } static void set_popup_sensitivity(GtkTreePath * path) { if (gtk_tree_path_get_depth(path) == 2) { GtkTreeIter iter; gboolean val_cdda; gboolean val_cdda_free; cdda_drive_t * drive; gtk_tree_model_get_iter(GTK_TREE_MODEL(music_store), &iter, path); val_cdda = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(music_store), &iter) > 0; gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter, MS_COL_DATA, &drive, -1); val_cdda_free = (drive->is_used == 0) ? TRUE : FALSE; gtk_widget_set_sensitive(cdda_record__addlist, val_cdda); gtk_widget_set_sensitive(cdda_record__addlist_albummode, val_cdda); #ifdef HAVE_CDDB gtk_widget_set_sensitive(cdda_record__cddb, val_cdda); gtk_widget_set_sensitive(cdda_record__cddb_submit, val_cdda); #endif /* HAVE_CDDB */ #ifdef HAVE_CD_RIPPER gtk_widget_set_sensitive(cdda_record__rip, val_cdda && val_cdda_free); #endif /* HAVE_CD_RIPPER */ gtk_widget_set_sensitive(cdda_record__eject, val_cdda_free); gtk_widget_set_sensitive(cdda_record__disc_info, val_cdda); } } static void add_path_to_playlist(GtkTreePath * path, GtkTreeIter * piter, int new_tab) { int depth = gtk_tree_path_get_depth(path); gtk_tree_selection_select_path(music_select, path); if (new_tab) { char * name; GtkTreeIter iter; gtk_tree_model_get_iter(GTK_TREE_MODEL(music_store), &iter, path); gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter, MS_COL_NAME, &name, -1); playlist_tab_new_if_nonempty(name); g_free(name); } switch (depth) { case 1: cdda_store__addlist_defmode(piter); break; case 2: cdda_record__addlist_defmode(piter); break; case 3: cdda_track__addlist_cb(piter); break; } } /************************************************/ /* music store interface */ /* create toplevel Music Store node for CD Audio */ void create_cdda_node(void) { GtkTreeIter iter; store_t * data; if ((data = (store_t *)malloc(sizeof(store_t))) == NULL) { fprintf(stderr, "create_cdda_node: malloc error\n"); return; } data->type = STORE_TYPE_CDDA; gtk_tree_store_insert(music_store, &iter, NULL, 0); gtk_tree_store_set(music_store, &iter, MS_COL_NAME, _("CD Audio"), MS_COL_SORT, "000", MS_COL_FONT, PANGO_WEIGHT_BOLD, MS_COL_DATA, data, -1); if (options.enable_ms_tree_icons) { gtk_tree_store_set(music_store, &iter, MS_COL_ICON, icon_cdda, -1); } } int store_cdda_iter_is_track(GtkTreeIter * iter) { GtkTreePath * p = gtk_tree_model_get_path(GTK_TREE_MODEL(music_store), iter); int ret = (gtk_tree_path_get_depth(p) == 3); gtk_tree_path_free(p); return ret; } void store_cdda_iter_addlist_defmode(GtkTreeIter * ms_iter, GtkTreeIter * pl_iter, int new_tab) { GtkTreePath * p = gtk_tree_model_get_path(GTK_TREE_MODEL(music_store), ms_iter); add_path_to_playlist(p, pl_iter, new_tab); gtk_tree_path_free(p); } void store_cdda_selection_changed(GtkTreeIter * tree_iter, GtkTextBuffer * buffer, GtkLabel * statusbar) { if (options.enable_mstore_statusbar) { set_status_bar_info(tree_iter, statusbar); } } gboolean store_cdda_event_cb(GdkEvent * event, GtkTreeIter * iter, GtkTreePath * path) { if (event->type == GDK_BUTTON_PRESS) { GdkEventButton * bevent = (GdkEventButton *) event; if (bevent->button == 3) { set_popup_sensitivity(path); switch (gtk_tree_path_get_depth(path)) { case 1: gtk_menu_popup(GTK_MENU(cdda_store_menu), NULL, NULL, NULL, NULL, bevent->button, bevent->time); break; case 2: gtk_menu_popup(GTK_MENU(cdda_record_menu), NULL, NULL, NULL, NULL, bevent->button, bevent->time); break; case 3: gtk_menu_popup(GTK_MENU(cdda_track_menu), NULL, NULL, NULL, NULL, bevent->button, bevent->time); break; } } } if (event->type == GDK_KEY_PRESS) { GdkEventKey * kevent = (GdkEventKey *) event; int i; switch (gtk_tree_path_get_depth(path)) { case 1: for (i = 0; cdda_store_keybinds[i].callback; ++i) if (kevent->keyval == cdda_store_keybinds[i].keyval1 || kevent->keyval == cdda_store_keybinds[i].keyval2) (cdda_store_keybinds[i].callback)(NULL); break; case 2: for (i = 0; cdda_record_keybinds[i].callback; ++i) if (kevent->keyval == cdda_record_keybinds[i].keyval1 || kevent->keyval == cdda_record_keybinds[i].keyval2) (cdda_record_keybinds[i].callback)(NULL); break; case 3: for (i = 0; cdda_track_keybinds[i].callback; ++i) if (kevent->keyval == cdda_track_keybinds[i].keyval1 || kevent->keyval == cdda_track_keybinds[i].keyval2) (cdda_track_keybinds[i].callback)(NULL); break; } } return FALSE; } void store_cdda_load_icons(void) { char path[MAXLEN]; sprintf(path, "%s/%s", AQUALUNG_DATADIR, "ms-cdda.png"); icon_cdda = gdk_pixbuf_new_from_file (path, NULL); sprintf(path, "%s/%s", AQUALUNG_DATADIR, "ms-cdda-disk.png"); icon_cdda_disc = gdk_pixbuf_new_from_file (path, NULL); sprintf(path, "%s/%s", AQUALUNG_DATADIR, "ms-cdda-nodisk.png"); icon_cdda_nodisc = gdk_pixbuf_new_from_file (path, NULL); } void store_cdda_create_popup_menu(void) { /* create popup menu for cdda_record tree items */ cdda_record_menu = gtk_menu_new(); register_toplevel_window(cdda_record_menu, TOP_WIN_SKIN); cdda_record__addlist = gtk_menu_item_new_with_label(_("Add to playlist")); cdda_record__addlist_albummode = gtk_menu_item_new_with_label(_("Add to playlist (Album mode)")); cdda_record__separator1 = gtk_separator_menu_item_new(); #ifdef HAVE_CDDB cdda_record__cddb = gtk_menu_item_new_with_label(_("CDDB query for this CD...")); cdda_record__cddb_submit = gtk_menu_item_new_with_label(_("Submit CD to CDDB database...")); #endif /* HAVE_CDDB */ #ifdef HAVE_CD_RIPPER cdda_record__rip = gtk_menu_item_new_with_label(_("Rip CD...")); #endif /* HAVE_CD_RIPPER */ cdda_record__disc_info = gtk_menu_item_new_with_label(_("Disc info...")); cdda_record__separator2 = gtk_separator_menu_item_new(); cdda_record__drive_info = gtk_menu_item_new_with_label(_("Drive info...")); cdda_record__eject = gtk_menu_item_new_with_label(_("Eject")); gtk_menu_shell_append(GTK_MENU_SHELL(cdda_record_menu), cdda_record__addlist); gtk_menu_shell_append(GTK_MENU_SHELL(cdda_record_menu), cdda_record__addlist_albummode); gtk_menu_shell_append(GTK_MENU_SHELL(cdda_record_menu), cdda_record__separator1); #ifdef HAVE_CDDB gtk_menu_shell_append(GTK_MENU_SHELL(cdda_record_menu), cdda_record__cddb); gtk_menu_shell_append(GTK_MENU_SHELL(cdda_record_menu), cdda_record__cddb_submit); #endif /* HAVE_CDDB */ #ifdef HAVE_CD_RIPPER gtk_menu_shell_append(GTK_MENU_SHELL(cdda_record_menu), cdda_record__rip); #endif /* HAVE_CD_RIPPER */ gtk_menu_shell_append(GTK_MENU_SHELL(cdda_record_menu), cdda_record__disc_info); gtk_menu_shell_append(GTK_MENU_SHELL(cdda_record_menu), cdda_record__separator2); gtk_menu_shell_append(GTK_MENU_SHELL(cdda_record_menu), cdda_record__drive_info); gtk_menu_shell_append(GTK_MENU_SHELL(cdda_record_menu), cdda_record__eject); g_signal_connect_swapped(G_OBJECT(cdda_record__addlist), "activate", G_CALLBACK(cdda_record__addlist_cb), NULL); g_signal_connect_swapped(G_OBJECT(cdda_record__addlist_albummode), "activate", G_CALLBACK(cdda_record__addlist_albummode_cb), NULL); #ifdef HAVE_CDDB g_signal_connect_swapped(G_OBJECT(cdda_record__cddb), "activate", G_CALLBACK(cdda_record__cddb_cb), NULL); g_signal_connect_swapped(G_OBJECT(cdda_record__cddb_submit), "activate", G_CALLBACK(cdda_record__cddb_submit_cb), NULL); #endif /* HAVE_CDDB */ #ifdef HAVE_CD_RIPPER g_signal_connect_swapped(G_OBJECT(cdda_record__rip), "activate", G_CALLBACK(cdda_record__rip_cb), NULL); #endif /* HAVE_CD_RIPPER */ g_signal_connect_swapped(G_OBJECT(cdda_record__disc_info), "activate", G_CALLBACK(cdda_record__disc_cb), NULL); g_signal_connect_swapped(G_OBJECT(cdda_record__drive_info), "activate", G_CALLBACK(cdda_record__drive_cb), NULL); g_signal_connect_swapped(G_OBJECT(cdda_record__eject), "activate", G_CALLBACK(cdda_record__eject_cb), NULL); gtk_widget_show(cdda_record__addlist); gtk_widget_show(cdda_record__addlist_albummode); gtk_widget_show(cdda_record__separator1); #ifdef HAVE_CDDB gtk_widget_show(cdda_record__cddb); gtk_widget_show(cdda_record__cddb_submit); #endif /* HAVE_CDDB */ #ifdef HAVE_CD_RIPPER gtk_widget_show(cdda_record__rip); #endif /* HAVE_CD_RIPPER */ gtk_widget_show(cdda_record__disc_info); gtk_widget_show(cdda_record__separator2); gtk_widget_show(cdda_record__drive_info); gtk_widget_show(cdda_record__eject); /* create popup menu for cdda_track tree items */ cdda_track_menu = gtk_menu_new(); register_toplevel_window(cdda_track_menu, TOP_WIN_SKIN); cdda_track__addlist = gtk_menu_item_new_with_label(_("Add to playlist")); gtk_menu_shell_append(GTK_MENU_SHELL(cdda_track_menu), cdda_track__addlist); g_signal_connect_swapped(G_OBJECT(cdda_track__addlist), "activate", G_CALLBACK(cdda_track__addlist_cb), NULL); gtk_widget_show(cdda_track__addlist); /* create popup menu for cdda_store tree items */ cdda_store_menu = gtk_menu_new(); register_toplevel_window(cdda_store_menu, TOP_WIN_SKIN); cdda_store__addlist = gtk_menu_item_new_with_label(_("Add to playlist")); cdda_store__addlist_albummode = gtk_menu_item_new_with_label(_("Add to playlist (Album mode)")); gtk_menu_shell_append(GTK_MENU_SHELL(cdda_store_menu), cdda_store__addlist); gtk_menu_shell_append(GTK_MENU_SHELL(cdda_store_menu), cdda_store__addlist_albummode); g_signal_connect_swapped(G_OBJECT(cdda_store__addlist), "activate", G_CALLBACK(cdda_store__addlist_cb), NULL); g_signal_connect_swapped(G_OBJECT(cdda_store__addlist_albummode), "activate", G_CALLBACK(cdda_store__addlist_albummode_cb), NULL); gtk_widget_show(cdda_store__addlist); gtk_widget_show(cdda_store__addlist_albummode); } #endif /* HAVE_CDDA */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/store_file.h0000644000175000001440000000574210762236020014213 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: store_file.h 1007 2008-02-26 21:33:41Z peterszilagyi $ */ #ifndef _STORE_FILE_H #define _STORE_FILE_H #include enum { BATCH_TAG_TITLE = (1 << 0), BATCH_TAG_ARTIST = (1 << 1), BATCH_TAG_ALBUM = (1 << 2), BATCH_TAG_COMMENT = (1 << 3), BATCH_TAG_YEAR = (1 << 4), BATCH_TAG_TRACKNO = (1 << 5) }; int store_file_iter_is_track(GtkTreeIter * iter); void store_file_iter_addlist_defmode(GtkTreeIter * ms_iter, GtkTreeIter * pl_iter, int new_tab); void store_file_selection_changed(GtkTreeIter * iter, GtkTextBuffer * buffer, GtkLabel * statusbar); gboolean store_file_event_cb(GdkEvent * event, GtkTreeIter * iter, GtkTreePath * path); void store_file_load_icons(void); void store_file_create_popup_menu(void); void store_file_insert_progress_bar(GtkWidget * vbox); void store_file_set_toolbar_sensitivity(GtkTreeIter * iter, GtkWidget * edit, GtkWidget * add, GtkWidget * remove); void store_file_toolbar__edit_cb(gpointer data); void store_file_toolbar__add_cb(gpointer data); void store_file_toolbar__remove_cb(gpointer data); gboolean store_file_remove_track(GtkTreeIter * iter); gboolean store_file_remove_record(GtkTreeIter * iter); gboolean store_file_remove_artist(GtkTreeIter * iter); gboolean store_file_remove_store(GtkTreeIter * iter); void store_file_progress_bar_hide(void); void store__add_cb(gpointer data); void store_file_load(char * file, char * sort); void store_file_save(GtkTreeIter * iter_store); void store__addlist_defmode(gpointer data); void artist__addlist_defmode(gpointer data); void record__addlist_defmode(gpointer data); void track__addlist_cb(gpointer data); typedef struct { int type; int dirty; int readonly; int use_relative_paths; char * file; char * comment; } store_data_t; typedef struct { char * comment; } artist_data_t; typedef struct { int year; char * comment; } record_data_t; typedef struct { char * file; float duration; /* length in seconds */ float volume; /* average volume in dBFS */ float rva; /* manual RVA in dB */ int use_rva; /* use manual RVA */ char * comment; unsigned size; /* file size in bytes */ } track_data_t; #endif /* _STORE_FILE_H */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/store_file.c0000644000175000001440000041567711324131225014216 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: store_file.c 1092 2010-01-03 15:58:59Z peterszilagyi $ */ #include #include #include #include #include #include #include #include #include #include #include "common.h" #include "utils.h" #include "utils_gui.h" #include "build_store.h" #include "cddb_lookup.h" #include "core.h" #include "cover.h" #include "file_info.h" #include "decoder/file_decoder.h" #include "metadata_api.h" #include "httpc.h" #include "options.h" #include "volume.h" #include "playlist.h" #include "search.h" #include "i18n.h" #include "music_browser.h" #include "store_file.h" #include "export.h" extern options_t options; extern GtkListStore * ms_pathlist_store; extern char pl_color_inactive[14]; extern GtkWidget * browser_window; extern GtkTreeStore * music_store; extern GtkTreeSelection * music_select; extern GtkWidget * music_tree; int stop_adding_to_playlist; int ms_progress_bar_semaphore; int ms_progress_bar_num; int ms_progress_bar_den; GtkWidget * ms_progress_bar; GtkWidget * ms_progress_bar_container; GtkWidget * ms_progress_bar_stop_button; /* popup menus for tree items */ GtkWidget * store_menu; GtkWidget * store__addlist; GtkWidget * store__addlist_albummode; GtkWidget * store__separator1; GtkWidget * store__add; GtkWidget * store__build; GtkWidget * store__edit; #ifdef HAVE_EXPORT GtkWidget * store__export; #endif /* HAVE_EXPORT */ GtkWidget * store__save; GtkWidget * store__remove; GtkWidget * store__separator2; GtkWidget * store__addart; GtkWidget * store__separator3; GtkWidget * store__volume; GtkWidget * store__volume_menu; GtkWidget * store__volume_unmeasured; GtkWidget * store__volume_all; GtkWidget * store__search; GtkWidget * artist_menu; GtkWidget * artist__addlist; GtkWidget * artist__addlist_albummode; GtkWidget * artist__separator1; GtkWidget * artist__add; GtkWidget * artist__edit; #ifdef HAVE_EXPORT GtkWidget * artist__export; #endif /* HAVE_EXPORT */ GtkWidget * artist__remove; GtkWidget * artist__separator2; GtkWidget * artist__addrec; GtkWidget * artist__separator3; GtkWidget * artist__volume; GtkWidget * artist__volume_menu; GtkWidget * artist__volume_unmeasured; GtkWidget * artist__volume_all; GtkWidget * artist__search; GtkWidget * record_menu; GtkWidget * record__addlist; GtkWidget * record__addlist_albummode; GtkWidget * record__separator1; GtkWidget * record__add; GtkWidget * record__edit; #ifdef HAVE_EXPORT GtkWidget * record__export; #endif /* HAVE_EXPORT */ GtkWidget * record__remove; GtkWidget * record__separator2; GtkWidget * record__addtrk; #ifdef HAVE_CDDB GtkWidget * record__cddb; GtkWidget * record__cddb_submit; #endif /* HAVE_CDDB */ GtkWidget * record__separator3; GtkWidget * record__volume; GtkWidget * record__volume_menu; GtkWidget * record__volume_unmeasured; GtkWidget * record__volume_all; GtkWidget * record__search; GtkWidget * track_menu; GtkWidget * track__addlist; GtkWidget * track__separator1; GtkWidget * track__add; GtkWidget * track__edit; #ifdef HAVE_EXPORT GtkWidget * track__export; #endif /* HAVE_EXPORT */ GtkWidget * track__remove; GtkWidget * track__separator2; GtkWidget * track__fileinfo; GtkWidget * track__separator3; GtkWidget * track__volume; GtkWidget * track__volume_menu; GtkWidget * track__volume_unmeasured; GtkWidget * track__volume_all; GtkWidget * track__search; extern GdkPixbuf * icon_store; GdkPixbuf * icon_artist; GdkPixbuf * icon_record; GdkPixbuf * icon_track; GtkWidget * store__tag; GtkWidget * artist__tag; GtkWidget * record__tag; GtkWidget * track__tag; typedef struct _batch_tag_t { char filename[MAXLEN]; char title[MAXLEN]; char artist[MAXLEN]; char album[MAXLEN]; char comment[MAXLEN]; char year[MAXLEN]; int trackno; struct _batch_tag_t * next; } batch_tag_t; batch_tag_t * batch_tag_root = NULL; void artist__add_cb(gpointer data); void record__add_cb(gpointer data); void track__add_cb(gpointer data); void store__edit_cb(gpointer data); void artist__edit_cb(gpointer data); void record__edit_cb(gpointer data); void track__edit_cb(gpointer data); void store__remove_cb(gpointer data); void artist__remove_cb(gpointer data); void record__remove_cb(gpointer data); void track__remove_cb(gpointer data); #ifdef HAVE_EXPORT void store__export_cb(gpointer data); void artist__export_cb(gpointer data); void record__export_cb(gpointer data); void track__export_cb(gpointer data); #endif /* HAVE_EXPORT */ void store__build_cb(gpointer data); void store__save_cb(gpointer data); void store__save_all_cb(gpointer data); void store__volume_unmeasured_cb(gpointer data); void store__volume_all_cb(gpointer data); void artist__volume_unmeasured_cb(gpointer data); void artist__volume_all_cb(gpointer data); void record__volume_unmeasured_cb(gpointer data); void record__volume_all_cb(gpointer data); void track__volume_unmeasured_cb(gpointer data); void track__volume_all_cb(gpointer data); void track__fileinfo_cb(gpointer data); struct keybinds store_keybinds[] = { {store__addlist_defmode, GDK_a, GDK_A, 0}, {store__add_cb, GDK_n, GDK_N, 0}, {store__build_cb, GDK_b, GDK_B, 0}, {store__edit_cb, GDK_e, GDK_E, 0}, {store__build_cb, GDK_u, GDK_U, 0}, {store__save_cb, GDK_s, GDK_S, 0}, {store__volume_unmeasured_cb, GDK_v, GDK_V, 0}, {store__remove_cb, GDK_Delete, GDK_KP_Delete, 0}, #ifdef HAVE_EXPORT {store__export_cb, GDK_x, GDK_X, 0}, #endif /* HAVE_EXPORT */ {artist__add_cb, GDK_n, GDK_N, GDK_CONTROL_MASK}, {NULL, 0, 0} }; struct keybinds artist_keybinds[] = { {artist__addlist_defmode, GDK_a, GDK_A, 0}, {artist__add_cb, GDK_n, GDK_N, 0}, {artist__edit_cb, GDK_e, GDK_E, 0}, {artist__volume_unmeasured_cb, GDK_v, GDK_V, 0}, {artist__remove_cb, GDK_Delete, GDK_KP_Delete, 0}, #ifdef HAVE_EXPORT {artist__export_cb, GDK_x, GDK_X, 0}, #endif /* HAVE_EXPORT */ {record__add_cb, GDK_n, GDK_N, GDK_CONTROL_MASK}, {NULL, 0, 0} }; struct keybinds record_keybinds[] = { {record__addlist_defmode, GDK_a, GDK_A, 0}, {record__add_cb, GDK_n, GDK_N, 0}, {record__edit_cb, GDK_e, GDK_E, 0}, {record__volume_unmeasured_cb, GDK_v, GDK_V, 0}, {record__remove_cb, GDK_Delete, GDK_KP_Delete, 0}, #ifdef HAVE_EXPORT {record__export_cb, GDK_x, GDK_X, 0}, #endif /* HAVE_EXPORT */ {track__add_cb, GDK_n, GDK_N, GDK_CONTROL_MASK}, {NULL, 0, 0} }; struct keybinds track_keybinds[] = { {track__addlist_cb, GDK_a, GDK_A, 0}, {track__add_cb, GDK_n, GDK_N, 0}, {track__edit_cb, GDK_e, GDK_E, 0}, {track__volume_unmeasured_cb, GDK_v, GDK_V, 0}, {track__remove_cb, GDK_Delete, GDK_KP_Delete, 0}, {track__fileinfo_cb, GDK_i, GDK_I, 0}, #ifdef HAVE_EXPORT {track__export_cb, GDK_x, GDK_X, 0}, #endif /* HAVE_EXPORT */ {NULL, 0, 0} }; void store_data_free(store_data_t * data) { free(data->file); if (data->comment != NULL) { free(data->comment); } free(data); } void artist_data_free(artist_data_t * data) { if (data->comment != NULL) { free(data->comment); } free(data); } void record_data_free(record_data_t * data) { if (data->comment != NULL) { free(data->comment); } free(data); } void track_data_free(track_data_t * data) { free(data->file); if (data->comment != NULL) { free(data->comment); } free(data); } gboolean store_file_remove_track(GtkTreeIter * iter) { track_data_t * data; gtk_tree_model_get(GTK_TREE_MODEL(music_store), iter, MS_COL_DATA, &data, -1); track_data_free(data); return gtk_tree_store_remove(music_store, iter); } gboolean store_file_remove_record(GtkTreeIter * iter) { record_data_t * data; GtkTreeIter track_iter; int i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &track_iter, iter, i++)) { store_file_remove_track(&track_iter); } gtk_tree_model_get(GTK_TREE_MODEL(music_store), iter, MS_COL_DATA, &data, -1); record_data_free(data); return gtk_tree_store_remove(music_store, iter); } gboolean store_file_remove_artist(GtkTreeIter * iter) { artist_data_t * data; GtkTreeIter record_iter; int i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &record_iter, iter, i++)) { store_file_remove_record(&record_iter); } gtk_tree_model_get(GTK_TREE_MODEL(music_store), iter, MS_COL_DATA, &data, -1); artist_data_free(data); return gtk_tree_store_remove(music_store, iter); } gboolean store_file_remove_store(GtkTreeIter * iter) { store_data_t * data; GtkTreeIter artist_iter; int i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &artist_iter, iter, i++)) { store_file_remove_artist(&artist_iter); } gtk_tree_model_get(GTK_TREE_MODEL(music_store), iter, MS_COL_DATA, &data, -1); store_data_free(data); return gtk_tree_store_remove(music_store, iter); } void create_dialog_layout(char * title, GtkWidget ** dialog, GtkWidget ** table, int rows) { *dialog = gtk_dialog_new_with_buttons(title, GTK_WINDOW(browser_window), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL); gtk_widget_set_size_request(*dialog, 400, -1); gtk_window_set_position(GTK_WINDOW(*dialog), GTK_WIN_POS_CENTER_ON_PARENT); gtk_dialog_set_default_response(GTK_DIALOG(*dialog), GTK_RESPONSE_ACCEPT); *table = gtk_table_new(rows, 2, FALSE); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(*dialog)->vbox), *table, FALSE, TRUE, 2); } void insert_comment_text_view(GtkWidget * vbox, GtkTextBuffer ** buffer, char * text) { GtkWidget * hbox; GtkWidget * viewport; GtkWidget * scrwin; GtkWidget * label; GtkWidget * view; hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 2); label = gtk_label_new(_("Comments:")); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5); viewport = gtk_viewport_new(NULL, NULL); gtk_box_pack_start(GTK_BOX(vbox), viewport, TRUE, TRUE, 2); scrwin = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrwin), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_container_add(GTK_CONTAINER(viewport), scrwin); *buffer = gtk_text_buffer_new(NULL); if (text != NULL) { gtk_text_buffer_set_text(GTK_TEXT_BUFFER(*buffer), text, -1); } view = gtk_text_view_new_with_buffer(*buffer); gtk_widget_set_size_request(view, -1, 100); gtk_text_view_set_left_margin(GTK_TEXT_VIEW(view), 3); gtk_text_view_set_right_margin(GTK_TEXT_VIEW(view), 3); gtk_text_view_set_editable(GTK_TEXT_VIEW(view), TRUE); gtk_container_add(GTK_CONTAINER(scrwin), view); } void browse_button_store_clicked(GtkButton * button, gpointer data) { file_chooser_with_entry(_("Please select the xml file for this store."), browser_window, GTK_FILE_CHOOSER_ACTION_SAVE, FILE_CHOOSER_FILTER_STORE, (GtkWidget *)data, options.storedir); } int add_store_dialog(char * name, store_data_t ** data) { GtkWidget * dialog; GtkWidget * table; GtkWidget * name_entry; GtkWidget * file_entry; GtkTextBuffer * buffer; GtkTextIter iter_start; GtkTextIter iter_end; create_dialog_layout(_("Create empty store"), &dialog, &table, 2); insert_label_entry(table, _("Visible name:"), &name_entry, NULL, 0, 1, TRUE); insert_label_entry_browse(table, _("Filename:"), &file_entry, options.storedir, 1, 2, browse_button_store_clicked); insert_comment_text_view(GTK_DIALOG(dialog)->vbox, &buffer, NULL); gtk_widget_grab_focus(name_entry); gtk_widget_show_all(dialog); display: name[0] = '\0'; if (aqualung_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { const char * pfile = g_filename_from_utf8(gtk_entry_get_text(GTK_ENTRY(file_entry)), -1, NULL, NULL, NULL); char file[MAXLEN]; strncpy(name, gtk_entry_get_text(GTK_ENTRY(name_entry)), MAXLEN-1); if (name[0] == '\0') { gtk_widget_grab_focus(name_entry); goto display; } file[0] = '\0'; if (pfile == NULL || pfile[0] == '\0') { gtk_widget_grab_focus(file_entry); goto display; } if ((*data = (store_data_t *)calloc(1, sizeof(store_data_t))) == NULL) { fprintf(stderr, "add_store_dialog: calloc error\n"); return 0; } (*data)->type = STORE_TYPE_FILE; normalize_filename(pfile, file); free_strdup(&(*data)->file, file); strncpy(options.storedir, file, MAXLEN-1); gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(buffer), &iter_start, 0); gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(buffer), &iter_end, -1); free_strdup(&(*data)->comment, gtk_text_buffer_get_text(GTK_TEXT_BUFFER(buffer), &iter_start, &iter_end, TRUE)); gtk_widget_destroy(dialog); return 1; } else { gtk_widget_destroy(dialog); return 0; } } int edit_store_dialog(char * name, store_data_t * data) { GtkWidget * dialog; GtkWidget * table; GtkWidget * name_entry; GtkWidget * file_entry; GtkWidget * rel_check; GtkTextBuffer * buffer; GtkTextIter iter_start; GtkTextIter iter_end; char * utf8; create_dialog_layout(_("Edit Store"), &dialog, &table, 3); insert_label_entry(table, _("Visible name:"), &name_entry, name, 0, 1, TRUE); utf8 = g_filename_to_utf8(data->file, -1, NULL, NULL, NULL); insert_label_entry(table, _("Filename:"), &file_entry, utf8, 1, 2, FALSE); g_free(utf8); insert_comment_text_view(GTK_DIALOG(dialog)->vbox, &buffer, data->comment); rel_check = gtk_check_button_new_with_label(_("Use relative paths in store file")); gtk_widget_set_name(rel_check, "check_on_window"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rel_check), data->use_relative_paths); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), rel_check, FALSE, FALSE, 5); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_hseparator_new(), FALSE, FALSE, 5); gtk_widget_grab_focus(name_entry); gtk_widget_show_all(dialog); display: name[0] = '\0'; if (aqualung_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { strcpy(name, gtk_entry_get_text(GTK_ENTRY(name_entry))); if (name[0] == '\0') { gtk_widget_grab_focus(name_entry); goto display; } gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(buffer), &iter_start, 0); gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(buffer), &iter_end, -1); free_strdup(&data->comment, gtk_text_buffer_get_text(GTK_TEXT_BUFFER(buffer), &iter_start, &iter_end, TRUE)); set_option_from_toggle(rel_check, &data->use_relative_paths); gtk_widget_destroy(dialog); return 1; } else { gtk_widget_destroy(dialog); return 0; } } void entry_copy_text(GtkEntry * entry, gpointer data) { gtk_entry_set_text(GTK_ENTRY(data), gtk_entry_get_text(entry)); gtk_widget_grab_focus((GtkWidget *)data); } int add_artist_dialog(char * name, char * sort, artist_data_t ** data) { GtkWidget * dialog; GtkWidget * table; GtkWidget * name_entry; GtkWidget * sort_entry; GtkTextBuffer * buffer; GtkTextIter iter_start; GtkTextIter iter_end; create_dialog_layout(_("Add Artist"), &dialog, &table, 2); insert_label_entry(table, _("Visible name:"), &name_entry, name, 0, 1, TRUE); insert_label_entry(table, _("Name to sort by:"), &sort_entry, sort, 1, 2, TRUE); insert_comment_text_view(GTK_DIALOG(dialog)->vbox, &buffer, NULL); g_signal_connect(G_OBJECT(name_entry), "activate", G_CALLBACK(entry_copy_text), sort_entry); gtk_widget_grab_focus(name_entry); gtk_widget_show_all(dialog); display: name[0] = '\0'; sort[0] = '\0'; if (aqualung_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { strcpy(name, gtk_entry_get_text(GTK_ENTRY(name_entry))); if (name[0] == '\0') { gtk_widget_grab_focus(name_entry); goto display; } strcpy(sort, gtk_entry_get_text(GTK_ENTRY(sort_entry))); if ((*data = (artist_data_t *)calloc(1, sizeof(artist_data_t))) == NULL) { fprintf(stderr, "add_artist_dialog: calloc error\n"); return 0; } gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(buffer), &iter_start, 0); gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(buffer), &iter_end, -1); free_strdup(&(*data)->comment, gtk_text_buffer_get_text(GTK_TEXT_BUFFER(buffer), &iter_start, &iter_end, TRUE)); gtk_widget_destroy(dialog); return 1; } else { gtk_widget_destroy(dialog); return 0; } } int edit_artist_dialog(char * name, char * sort, artist_data_t * data) { GtkWidget * dialog; GtkWidget * table; GtkWidget * name_entry; GtkWidget * sort_entry; GtkTextBuffer * buffer; GtkTextIter iter_start; GtkTextIter iter_end; create_dialog_layout(_("Edit Artist"), &dialog, &table, 2); insert_label_entry(table, _("Visible name:"), &name_entry, name, 0, 1, TRUE); insert_label_entry(table, _("Name to sort by:"), &sort_entry, sort, 1, 2, TRUE); insert_comment_text_view(GTK_DIALOG(dialog)->vbox, &buffer, data->comment); g_signal_connect(G_OBJECT(name_entry), "activate", G_CALLBACK(entry_copy_text), sort_entry); gtk_widget_grab_focus(name_entry); gtk_widget_show_all(dialog); display: name[0] = '\0'; sort[0] = '\0'; if (aqualung_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { strcpy(name, gtk_entry_get_text(GTK_ENTRY(name_entry))); if (name[0] == '\0') { gtk_widget_grab_focus(name_entry); goto display; } strcpy(sort, gtk_entry_get_text(GTK_ENTRY(sort_entry))); gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(buffer), &iter_start, 0); gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(buffer), &iter_end, -1); free_strdup(&data->comment, gtk_text_buffer_get_text(GTK_TEXT_BUFFER(buffer), &iter_start, &iter_end, TRUE)); gtk_widget_destroy(dialog); return 1; } else { gtk_widget_destroy(dialog); return 0; } } void browse_button_record_clicked(GtkButton * button, gpointer data) { GtkListStore * store = (GtkListStore *)data; GtkTreeIter iter; GSList * lfiles, * node; lfiles = file_chooser(_("Please select the audio files for this record."), browser_window, GTK_FILE_CHOOSER_ACTION_OPEN, FILE_CHOOSER_FILTER_AUDIO, TRUE, options.audiodir); for (node = lfiles; node; node = node->next) { char * filename = (char *)node->data; if (filename[strlen(filename)-1] != '/') { char * utf8 = g_filename_to_utf8(filename, -1, NULL, NULL, NULL); gtk_list_store_append(store, &iter); gtk_list_store_set(store, &iter, 0, utf8, -1); g_free(utf8); } g_free(node->data); } g_slist_free(lfiles); } void clicked_tracklist_header(GtkWidget * widget, gpointer data) { GtkListStore * store = (GtkListStore *)data; gtk_list_store_clear(store); } int add_record_dialog(char * name, char * sort, char *** strings, record_data_t ** data) { GtkWidget * dialog; GtkWidget * table; GtkWidget * hbox; GtkWidget * name_entry; GtkWidget * sort_entry; GtkWidget * year_spin; GtkWidget * list_label; GtkWidget * viewport; GtkWidget * scrolled_win; GtkWidget * tracklist_tree; GtkListStore * store; GtkCellRenderer * cell; GtkTreeViewColumn * column; GtkTreeIter iter; gchar * str; GtkWidget * browse_button; GtkTextBuffer * buffer; GtkTextIter iter_start; GtkTextIter iter_end; int n, i; create_dialog_layout(_("Add Record"), &dialog, &table, 3); insert_label_entry(table, _("Visible name:"), &name_entry, name, 0, 1, TRUE); insert_label_spin(table, _("Year:"), &year_spin, 0, 1, 2); insert_label_entry(table, _("Name to sort by:"), &sort_entry, sort, 2, 3, TRUE); g_signal_connect(G_OBJECT(name_entry), "activate", G_CALLBACK(entry_copy_text), sort_entry); g_signal_connect(G_OBJECT(year_spin), "activate", G_CALLBACK(entry_copy_text), sort_entry); list_label = gtk_label_new(_("Auto-create tracks from these files:")); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), list_label, FALSE, FALSE, 5); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, TRUE, 2); viewport = gtk_viewport_new(NULL, NULL); gtk_widget_set_size_request(viewport, -1, 150); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), viewport, TRUE, TRUE, 2); scrolled_win = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_win), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_container_add(GTK_CONTAINER(viewport), scrolled_win); /* setup track list */ store = gtk_list_store_new(1, G_TYPE_STRING); tracklist_tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store)); gtk_container_add(GTK_CONTAINER(scrolled_win), tracklist_tree); gtk_widget_set_size_request(tracklist_tree, 250, 50); cell = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes(_("Clear list"), cell, "text", 0, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(tracklist_tree), GTK_TREE_VIEW_COLUMN(column)); gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(tracklist_tree), TRUE); g_signal_connect(G_OBJECT(column->button), "clicked", G_CALLBACK(clicked_tracklist_header), store); gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(store), 0, GTK_SORT_ASCENDING); browse_button = gui_stock_label_button(_("_Add files..."), GTK_STOCK_ADD); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), browse_button, FALSE, TRUE, 2); g_signal_connect(G_OBJECT(browse_button), "clicked", G_CALLBACK(browse_button_record_clicked), store); insert_comment_text_view(GTK_DIALOG(dialog)->vbox, &buffer, NULL); gtk_widget_grab_focus(name_entry); gtk_widget_show_all(dialog); display: name[0] = '\0'; sort[0] = '\0'; if (aqualung_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { strcpy(name, gtk_entry_get_text(GTK_ENTRY(name_entry))); if (name[0] == '\0') { gtk_widget_grab_focus(name_entry); goto display; } strcpy(sort, gtk_entry_get_text(GTK_ENTRY(sort_entry))); if ((n = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(store), NULL)) > 0) { gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter); if (!(*strings = calloc(n + 1, sizeof(char *)))) { fprintf(stderr, "add_record_dialog(): calloc error\n"); return 0; } for (i = 0; i < n; i++) { char * filename; gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, 0, &str, -1); gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter); filename = g_filename_from_utf8(str, -1, NULL, NULL, NULL); if (!((*strings)[i] = calloc(strlen(filename)+1, sizeof(char)))) { fprintf(stderr, "add_record_dialog(): calloc error\n"); return 0; } strcpy((*strings)[i], filename); g_free(str); g_free(filename); } (*strings)[i] = NULL; } if ((*data = (record_data_t *)calloc(1, sizeof(record_data_t))) == NULL) { fprintf(stderr, "add_record_dialog: calloc error\n"); return 0; } (*data)->year = gtk_spin_button_get_value(GTK_SPIN_BUTTON(year_spin)); gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(buffer), &iter_start, 0); gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(buffer), &iter_end, -1); free_strdup(&(*data)->comment, gtk_text_buffer_get_text(GTK_TEXT_BUFFER(buffer), &iter_start, &iter_end, TRUE)); gtk_widget_destroy(dialog); return 1; } else { gtk_widget_destroy(dialog); return 0; } } int edit_record_dialog(char * name, char * sort, record_data_t * data) { GtkWidget * dialog; GtkWidget * table; GtkWidget * name_entry; GtkWidget * sort_entry; GtkWidget * year_spin; GtkTextBuffer * buffer; GtkTextIter iter_start; GtkTextIter iter_end; create_dialog_layout(_("Edit Record"), &dialog, &table, 3); insert_label_entry(table, _("Visible name:"), &name_entry, name, 0, 1, TRUE); insert_label_spin(table, _("Year:"), &year_spin, data->year, 1, 2); insert_label_entry(table, _("Name to sort by:"), &sort_entry, sort, 2, 3, TRUE); insert_comment_text_view(GTK_DIALOG(dialog)->vbox, &buffer, data->comment); g_signal_connect(G_OBJECT(name_entry), "activate", G_CALLBACK(entry_copy_text), sort_entry); g_signal_connect(G_OBJECT(year_spin), "activate", G_CALLBACK(entry_copy_text), sort_entry); gtk_widget_grab_focus(name_entry); gtk_widget_show_all(dialog); display: name[0] = '\0'; sort[0] = '\0'; if (aqualung_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { strcpy(name, gtk_entry_get_text(GTK_ENTRY(name_entry))); if (name[0] == '\0') { gtk_widget_grab_focus(name_entry); goto display; } strcpy(sort, gtk_entry_get_text(GTK_ENTRY(sort_entry))); data->year = gtk_spin_button_get_value(GTK_SPIN_BUTTON(year_spin)); gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(buffer), &iter_start, 0); gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(buffer), &iter_end, -1); free_strdup(&data->comment, gtk_text_buffer_get_text(GTK_TEXT_BUFFER(buffer), &iter_start, &iter_end, TRUE)); gtk_widget_destroy(dialog); return 1; } else { gtk_widget_destroy(dialog); return 0; } } void browse_button_track_clicked(GtkButton * button, gpointer data) { file_chooser_with_entry(_("Please select the audio file for this track."), browser_window, GTK_FILE_CHOOSER_ACTION_OPEN, FILE_CHOOSER_FILTER_AUDIO, (GtkWidget *)data, options.audiodir); } int add_track_dialog(char * name, char * sort, track_data_t ** data) { GtkWidget * dialog; GtkWidget * table; GtkWidget * name_entry; GtkWidget * sort_entry; GtkWidget * file_entry; GtkTextBuffer * buffer; GtkTextIter iter_start; GtkTextIter iter_end; create_dialog_layout(_("Add Track"), &dialog, &table, 3); insert_label_entry(table, _("Visible name:"), &name_entry, NULL, 0, 1, TRUE); insert_label_entry(table, _("Name to sort by:"), &sort_entry, NULL, 1, 2, TRUE); insert_label_entry_browse(table, _("Filename:"), &file_entry, options.audiodir, 2, 3, browse_button_track_clicked); insert_comment_text_view(GTK_DIALOG(dialog)->vbox, &buffer, NULL); gtk_widget_grab_focus(name_entry); gtk_widget_show_all(dialog); display: name[0] = '\0'; sort[0] = '\0'; if (aqualung_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { const char * pfile = g_filename_from_utf8(gtk_entry_get_text(GTK_ENTRY(file_entry)), -1, NULL, NULL, NULL); char file[MAXLEN]; float duration; strncpy(name, gtk_entry_get_text(GTK_ENTRY(name_entry)), MAXLEN-1); if (name[0] == '\0') { gtk_widget_grab_focus(name_entry); goto display; } file[0] = '\0'; if (pfile == NULL || pfile[0] == '\0') { gtk_widget_grab_focus(file_entry); goto display; } if ((*data = (track_data_t *)calloc(1, sizeof(track_data_t))) == NULL) { fprintf(stderr, "add_track_dialog: calloc error\n"); return 0; } strcpy(sort, gtk_entry_get_text(GTK_ENTRY(sort_entry))); normalize_filename(pfile, file); free_strdup(&(*data)->file, file); gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(buffer), &iter_start, 0); gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(buffer), &iter_end, -1); free_strdup(&(*data)->comment, gtk_text_buffer_get_text(GTK_TEXT_BUFFER(buffer), &iter_start, &iter_end, TRUE)); duration = get_file_duration((*data)->file); (*data)->duration = (duration > 0.0f) ? duration : 0.0f; (*data)->volume = 1.0f; gtk_widget_destroy(dialog); return 1; } else { gtk_widget_destroy(dialog); return 0; } } void use_rva_check_button_cb(GtkWidget * widget, gpointer data) { if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) { gtk_widget_set_sensitive((GtkWidget *)data, TRUE); } else { gtk_widget_set_sensitive((GtkWidget *)data, FALSE); } } void edit_track_done(GtkEntry * entry, gpointer data) { gtk_dialog_response(GTK_DIALOG(data), GTK_RESPONSE_ACCEPT); } int edit_track_dialog(char * name, char * sort, track_data_t * data) { GtkWidget * dialog; GtkWidget * table; GtkWidget * name_entry; GtkWidget * sort_entry; GtkWidget * file_entry; GtkTextBuffer * buffer; GtkTextIter iter_start; GtkTextIter iter_end; GtkWidget * table2; GtkWidget * duration_entry; GtkWidget * volume_entry; GtkWidget * check_button; GtkObject * adj_manual_rva; GtkWidget * spin_button; char str[MAXLEN]; char * utf8; create_dialog_layout(_("Edit Track"), &dialog, &table, 6); insert_label_entry(table, _("Visible name:"), &name_entry, name, 0, 1, TRUE); insert_label_entry(table, _("Name to sort by:"), &sort_entry, sort, 1, 2, TRUE); g_signal_connect(G_OBJECT(name_entry), "activate", G_CALLBACK(edit_track_done), dialog); utf8 = g_filename_to_utf8(data->file, -1, NULL, NULL, NULL); insert_label_entry_browse(table, _("Filename:"), &file_entry, utf8, 2, 3, browse_button_track_clicked); g_free(utf8); time2time(data->duration, str); insert_label_entry(table, _("Duration:"), &duration_entry, str, 3, 4, FALSE); if (data->volume <= 0.1f) { snprintf(str, MAXLEN-1, "%.1f dBFS", data->volume); } else { snprintf(str, MAXLEN-1, _("Unmeasured")); } insert_label_entry(table, _("Volume level:"), &volume_entry, str, 4, 5, FALSE); table2 = gtk_table_new(1, 2, FALSE); gtk_table_attach(GTK_TABLE(table), table2, 0, 2, 5, 6, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); check_button = gtk_check_button_new_with_label(_("Use manual RVA value [dB]")); gtk_widget_set_name(check_button, "check_on_window"); gtk_table_attach(GTK_TABLE(table2), check_button, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 5, 3); adj_manual_rva = gtk_adjustment_new(data->rva, -70.0f, 20.0f, 0.1f, 1.0f, 0.0f); spin_button = gtk_spin_button_new(GTK_ADJUSTMENT(adj_manual_rva), 0.3, 1); gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(spin_button), TRUE); gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(spin_button), FALSE); gtk_table_attach(GTK_TABLE(table2), spin_button, 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 3); g_signal_connect(G_OBJECT(check_button), "toggled", G_CALLBACK(use_rva_check_button_cb), (gpointer)spin_button); if (data->use_rva) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_button), TRUE); } else { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_button), FALSE); gtk_widget_set_sensitive(spin_button, FALSE); } insert_comment_text_view(GTK_DIALOG(dialog)->vbox, &buffer, data->comment); gtk_widget_grab_focus(name_entry); gtk_widget_show_all(dialog); display: name[0] = '\0'; sort[0] = '\0'; if (aqualung_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { const char * pfile = g_filename_from_utf8(gtk_entry_get_text(GTK_ENTRY(file_entry)), -1, NULL, NULL, NULL); char file[MAXLEN]; strncpy(name, gtk_entry_get_text(GTK_ENTRY(name_entry)), MAXLEN-1); if (name[0] == '\0') { gtk_widget_grab_focus(name_entry); goto display; } file[0] = '\0'; if (pfile == NULL || pfile[0] == '\0') { gtk_widget_grab_focus(file_entry); goto display; } strcpy(sort, gtk_entry_get_text(GTK_ENTRY(sort_entry))); normalize_filename(pfile, file); free_strdup(&data->file, file); gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(buffer), &iter_start, 0); gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(buffer), &iter_end, -1); free_strdup(&data->comment, gtk_text_buffer_get_text(GTK_TEXT_BUFFER(buffer), &iter_start, &iter_end, TRUE)); data->rva = gtk_adjustment_get_value(GTK_ADJUSTMENT(adj_manual_rva)); if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check_button))) { data->use_rva = 1; } else { data->use_rva = 0; } gtk_widget_destroy(dialog); return 1; } else { gtk_widget_destroy(dialog); return 0; } } int confirm_dialog(char * title, char * text) { int ret = message_dialog(title, browser_window, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, NULL, text); return (ret == GTK_RESPONSE_YES); } int is_store_path_readonly(GtkTreePath * p) { GtkTreeIter iter; GtkTreePath * path; store_data_t * data; path = gtk_tree_path_copy(p); while (gtk_tree_path_get_depth(path) > 1) { gtk_tree_path_up(path); } gtk_tree_model_get_iter(GTK_TREE_MODEL(music_store), &iter, path); gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter, MS_COL_DATA, &data, -1); gtk_tree_path_free(path); return data->readonly; } int is_store_iter_readonly(GtkTreeIter * i) { GtkTreePath * path = gtk_tree_model_get_path(GTK_TREE_MODEL(music_store), i); int ret = is_store_path_readonly(path); gtk_tree_path_free(path); return ret; } static void set_popup_sensitivity(GtkTreePath * path) { gboolean writable = !is_store_path_readonly(path); gboolean tag_free = (batch_tag_root == NULL); gtk_widget_set_sensitive(store__build, writable && !build_is_busy()); gtk_widget_set_sensitive(store__edit, writable); gtk_widget_set_sensitive(store__save, writable); gtk_widget_set_sensitive(store__addart, writable); gtk_widget_set_sensitive(store__volume, writable); gtk_widget_set_sensitive(artist__add, writable); gtk_widget_set_sensitive(artist__edit, writable); gtk_widget_set_sensitive(artist__remove, writable); gtk_widget_set_sensitive(artist__addrec, writable); gtk_widget_set_sensitive(artist__volume, writable); gtk_widget_set_sensitive(record__add, writable); gtk_widget_set_sensitive(record__edit, writable); gtk_widget_set_sensitive(record__remove, writable); gtk_widget_set_sensitive(record__addtrk, writable); #ifdef HAVE_CDDB gtk_widget_set_sensitive(record__cddb, writable); #endif /* HAVE_CDDB */ gtk_widget_set_sensitive(record__volume, writable); gtk_widget_set_sensitive(track__add, writable); gtk_widget_set_sensitive(track__edit, writable); gtk_widget_set_sensitive(track__remove, writable); gtk_widget_set_sensitive(track__volume, writable); gtk_widget_set_sensitive(store__tag, tag_free); gtk_widget_set_sensitive(artist__tag, tag_free); gtk_widget_set_sensitive(record__tag, tag_free); gtk_widget_set_sensitive(track__tag, tag_free); } static void add_path_to_playlist(GtkTreePath * path, GtkTreeIter * piter, int new_tab) { int depth = gtk_tree_path_get_depth(path); gtk_tree_selection_select_path(music_select, path); if (new_tab) { char * name; void * data; GtkTreeIter iter; gtk_tree_model_get_iter(GTK_TREE_MODEL(music_store), &iter, path); gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter, MS_COL_NAME, &name, MS_COL_DATA, &data, -1); if (depth == 1 && ((store_data_t *)data)->dirty) { playlist_tab_new_if_nonempty(name + 1); } else { playlist_tab_new_if_nonempty(name); } g_free(name); } switch (depth) { case 1: store__addlist_defmode(piter); break; case 2: artist__addlist_defmode(piter); break; case 3: record__addlist_defmode(piter); break; case 4: track__addlist_cb(piter); break; } } /****************************************/ void generic_remove_cb(char * title, int (* remove_cb)(GtkTreeIter *)) { GtkTreeIter iter; GtkTreeModel * model; int ok = 1; if (gtk_tree_selection_get_selected(music_select, &model, &iter)) { if (is_store_iter_readonly(&iter)) { return; } if (options.ms_confirm_removal) { char * name; char text[MAXLEN]; gtk_tree_model_get(model, &iter, MS_COL_NAME, &name, -1); snprintf(text, MAXLEN-1, _("Really remove \"%s\" from the Music Store?"), name); g_free(name); ok = confirm_dialog(title, text); } if (ok) { GtkTreeIter parent; music_store_mark_changed(&iter); gtk_tree_model_iter_parent(model, &parent, &iter); if (remove_cb(&iter)) { gtk_tree_selection_select_iter(music_select, &iter); } else { int last; if ((last = gtk_tree_model_iter_n_children(model, &parent))) { gtk_tree_model_iter_nth_child(model, &iter, &parent, last-1); gtk_tree_selection_select_iter(music_select, &iter); } else { gtk_tree_selection_select_iter(music_select, &parent); } } } } } /* returns the duration of the track */ float track_addlist_iter(GtkTreeIter iter_track, playlist_t * pl, GtkTreeIter * parent, GtkTreeIter * dest, float avg_voladj, int use_avg_voladj) { GtkTreeIter dest_parent; GtkTreeIter iter_artist; GtkTreeIter iter_record; GtkTreeIter list_iter; track_data_t * data; char list_str[MAXLEN]; char * artist_name; char * record_name; char * track_name; float voladj = 0.0f; char voladj_str[32]; char duration_str[MAXLEN]; file_decoder_t * fdec = NULL; playlist_data_t * pldata = NULL; gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter_track, MS_COL_NAME, &track_name, MS_COL_DATA, &data, -1); gtk_tree_model_iter_parent(GTK_TREE_MODEL(music_store), &iter_record, &iter_track); gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter_record, MS_COL_NAME, &record_name, -1); gtk_tree_model_iter_parent(GTK_TREE_MODEL(music_store), &iter_artist, &iter_record); gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter_artist, MS_COL_NAME, &artist_name, -1); if (parent != NULL || (dest != NULL && gtk_tree_model_iter_parent(GTK_TREE_MODEL(pl->store), &dest_parent, dest))) { GtkTreeIter * piter = (parent != NULL) ? parent : &dest_parent; playlist_data_t * pdata; gtk_tree_model_get(GTK_TREE_MODEL(pl->store), piter, PL_COL_DATA, &pdata, -1); if (pdata->artist && pdata->album && artist_name && record_name && !strcmp(pdata->artist, artist_name) && !strcmp(pdata->album, record_name)) { strcpy(list_str, track_name); } else { make_title_string(list_str, options.title_format, artist_name, record_name, track_name); } } else { make_title_string(list_str, options.title_format, artist_name, record_name, track_name); } if (options.rva_is_enabled) { if (options.rva_use_averaging && use_avg_voladj) { voladj = avg_voladj; } else { if (data->use_rva > 0) { voladj = data->rva; } else { if (data->volume <= 0.1f) { voladj = rva_from_volume(data->volume); } else { /* unmeasured, see if there is RVA data in the file */ if ((fdec == NULL) || !metadata_get_rva(fdec->meta, &voladj)) { voladj = options.rva_no_rva_voladj; } } } } } time2time(data->duration, duration_str); voladj2str(voladj, voladj_str); if ((pldata = playlist_data_new()) == NULL) { return 0; } pldata->artist = strdup(artist_name); pldata->album = strdup(record_name); pldata->title = strdup(track_name); pldata->file = strdup(data->file); pldata->voladj = voladj; pldata->duration = data->duration; pldata->size = data->size; pldata->flags = PL_FLAG_COVER; /* either parent or dest should be set, but not both */ gtk_tree_store_insert_before(pl->store, &list_iter, parent, dest); gtk_tree_store_set(pl->store, &list_iter, PL_COL_NAME, list_str, PL_COL_VADJ, voladj_str, PL_COL_DURA, duration_str, PL_COL_COLO, pl_color_inactive, PL_COL_FONT, PANGO_WEIGHT_NORMAL, PL_COL_DATA, pldata, -1); if (fdec != NULL) { file_decoder_close(fdec); file_decoder_delete(fdec); } g_free(track_name); g_free(record_name); g_free(artist_name); return data->duration; } void record_addlist_iter(GtkTreeIter iter_record, playlist_t * pl, GtkTreeIter * dest, int album_mode) { GtkTreeIter iter_track; GtkTreeIter list_iter; GtkTreeIter * plist_iter; int i; int nlevels; float volume; float voladj = 0.0f; float record_duration = 0.0f; playlist_data_t * pldata = NULL; if (gtk_tree_model_iter_n_children(GTK_TREE_MODEL(music_store), &iter_record) == 0) { return; } if (options.rva_is_enabled && options.rva_use_averaging) { /* save track volumes */ float * volumes = NULL; track_data_t * data; i = 0; nlevels = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &iter_track, &iter_record, i++)) { gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter_track, MS_COL_DATA, &data, -1); volume = data->volume; if (volume > 0.1f) { /* unmeasured */ volume = options.rva_refvol; } nlevels++; if ((volumes = realloc(volumes, nlevels * sizeof(float))) == NULL) { fprintf(stderr, "record__addlist_cb: realloc error\n"); return; } volumes[nlevels-1] = volume; } voladj = rva_from_multiple_volumes(nlevels, volumes); free(volumes); } if (album_mode) { GtkTreeIter iter_artist; char * record_name; char * artist_name; char list_str[MAXLEN]; if ((pldata = playlist_data_new()) == NULL) { return; } gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter_record, MS_COL_NAME, &record_name, -1); gtk_tree_model_iter_parent(GTK_TREE_MODEL(music_store), &iter_artist, &iter_record); gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter_artist, MS_COL_NAME, &artist_name, -1); snprintf(list_str, MAXLEN-1, "%s: %s", artist_name, record_name); pldata->artist = strdup(artist_name); pldata->album = strdup(record_name); gtk_tree_store_insert_before(pl->store, &list_iter, NULL, dest); gtk_tree_store_set(pl->store, &list_iter, PL_COL_NAME, list_str, PL_COL_VADJ, "", PL_COL_DURA, "00:00", PL_COL_COLO, pl_color_inactive, PL_COL_FONT, PANGO_WEIGHT_NORMAL, PL_COL_DATA, pldata, -1); g_free(record_name); g_free(artist_name); plist_iter = &list_iter; dest = NULL; } else { plist_iter = NULL; } i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &iter_track, &iter_record, i++)) { record_duration += track_addlist_iter(iter_track, pl, plist_iter, dest, voladj, options.rva_use_averaging); } if (album_mode) { char duration_str[MAXLEN]; pldata->duration = record_duration; time2time(record_duration, duration_str); gtk_tree_store_set(pl->store, &list_iter, PL_COL_DURA, duration_str, -1); } } typedef struct { GtkTreeIter iter_store; GtkTreeIter iter_artist; GtkTreeIter iter_record; GtkTreeIter dest; playlist_t * pl; int dest_null; int album_mode; int i_artist; int i_record; int count; } addlist_iter_t; void ms_progress_bar_update() { if (ms_progress_bar != NULL) { ++ms_progress_bar_num; gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(ms_progress_bar), (double)(ms_progress_bar_num) / ms_progress_bar_den); } } void ms_progress_bar_stop_clicked(GtkWidget * widget, gpointer data) { stop_adding_to_playlist = 1; } void ms_progress_bar_show(void) { ++ms_progress_bar_semaphore; if (ms_progress_bar != NULL) { return; } stop_adding_to_playlist = 0; playlist_stats_set_busy(); ms_progress_bar = gtk_progress_bar_new(); gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(ms_progress_bar), 0.0); gtk_box_pack_start(GTK_BOX(ms_progress_bar_container), ms_progress_bar, TRUE, TRUE, 0); ms_progress_bar_stop_button = gtk_button_new_with_label(_("Stop adding songs")); gtk_box_pack_start(GTK_BOX(ms_progress_bar_container), ms_progress_bar_stop_button, FALSE, FALSE, 0); g_signal_connect(G_OBJECT(ms_progress_bar_stop_button), "clicked", G_CALLBACK(ms_progress_bar_stop_clicked), NULL); gtk_widget_show_all(ms_progress_bar_container); } void store_file_progress_bar_hide(void) { if (ms_progress_bar != NULL) { gtk_widget_destroy(ms_progress_bar); ms_progress_bar = NULL; } if (ms_progress_bar_stop_button != NULL) { gtk_widget_destroy(ms_progress_bar_stop_button); ms_progress_bar_stop_button = NULL; } } void finalize_addlist_iter(addlist_iter_t * add_list) { ms_progress_bar_semaphore--; add_list->pl->ms_semaphore--; if (browser_window != NULL && ms_progress_bar_semaphore == 0) { store_file_progress_bar_hide(); if (add_list->pl == playlist_get_current()) { playlist_content_changed(add_list->pl); } gtk_tree_view_column_set_sizing(GTK_TREE_VIEW_COLUMN(add_list->pl->track_column), GTK_TREE_VIEW_COLUMN_AUTOSIZE); gtk_tree_view_column_set_sizing(GTK_TREE_VIEW_COLUMN(add_list->pl->rva_column), GTK_TREE_VIEW_COLUMN_AUTOSIZE); gtk_tree_view_column_set_sizing(GTK_TREE_VIEW_COLUMN(add_list->pl->length_column), GTK_TREE_VIEW_COLUMN_AUTOSIZE); ms_progress_bar_num = 0; ms_progress_bar_den = 0; } } gboolean artist_addlist_iter_cb(gpointer data) { addlist_iter_t * add_iter = (addlist_iter_t *)data; if (stop_adding_to_playlist) { goto finish; } if (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &add_iter->iter_record, &add_iter->iter_artist, add_iter->i_record++)) { if (!add_iter->dest_null && !gtk_tree_store_iter_is_valid(add_iter->pl->store, &add_iter->dest)) { add_iter->dest_null = 1; } record_addlist_iter(add_iter->iter_record, add_iter->pl, add_iter->dest_null ? NULL : &add_iter->dest, add_iter->album_mode); ms_progress_bar_update(); return TRUE; } finish: finalize_addlist_iter(add_iter); free(add_iter); return FALSE; } gboolean store_addlist_iter_cb(gpointer data) { addlist_iter_t * add_iter = (addlist_iter_t *)data; if (stop_adding_to_playlist) { goto finish; } if (add_iter->i_artist > 0 && gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &add_iter->iter_record, &add_iter->iter_artist, add_iter->i_record++)) { if (!add_iter->dest_null && !gtk_tree_store_iter_is_valid(add_iter->pl->store, &add_iter->dest)) { add_iter->dest_null = 1; } record_addlist_iter(add_iter->iter_record, add_iter->pl, add_iter->dest_null ? NULL : &add_iter->dest, add_iter->album_mode); return TRUE; } else { add_iter->i_record = 0; if (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &add_iter->iter_artist, &add_iter->iter_store, add_iter->i_artist++)) { ms_progress_bar_update(); return TRUE; } } finish: finalize_addlist_iter(add_iter); free(add_iter); return FALSE; } void artist_addlist_iter(GtkTreeIter iter_artist, playlist_t * pl, GtkTreeIter * dest, int album_mode) { addlist_iter_t * add_iter; if ((add_iter = (addlist_iter_t *)malloc(sizeof(addlist_iter_t))) == NULL) { fprintf(stderr, "malloc error in artist_adlist_iter\n"); return; } if ((add_iter->count = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(music_store), &iter_artist)) == 0) { free(add_iter); return; } add_iter->pl = pl; ms_progress_bar_den += add_iter->count; if (dest == NULL) { add_iter->dest_null = 1; } else { add_iter->dest_null = 0; add_iter->dest = *dest; } add_iter->iter_artist = iter_artist; add_iter->album_mode = album_mode; add_iter->i_record = 0; playlist_stats_set_busy(); ms_progress_bar_show(); pl->ms_semaphore++; aqualung_idle_add(artist_addlist_iter_cb, (gpointer)add_iter); } void store_addlist_iter(GtkTreeIter iter_store, playlist_t * pl, GtkTreeIter * dest, int album_mode) { addlist_iter_t * add_iter; if ((add_iter = (addlist_iter_t *)malloc(sizeof(addlist_iter_t))) == NULL) { fprintf(stderr, "malloc error in store_adlist_iter\n"); return; } if ((add_iter->count = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(music_store), &iter_store)) == 0) { free(add_iter); return; } add_iter->pl = pl; ms_progress_bar_den += add_iter->count; if (dest == NULL) { add_iter->dest_null = 1; } else { add_iter->dest_null = 0; add_iter->dest = *dest; } add_iter->iter_store = iter_store; add_iter->album_mode = album_mode; add_iter->i_artist = 0; playlist_stats_set_busy(); /* set sizing to fixed for speeding up adding new stuff */ gtk_tree_view_column_set_sizing(GTK_TREE_VIEW_COLUMN(pl->track_column), GTK_TREE_VIEW_COLUMN_FIXED); gtk_tree_view_column_set_sizing(GTK_TREE_VIEW_COLUMN(pl->rva_column), GTK_TREE_VIEW_COLUMN_FIXED); gtk_tree_view_column_set_sizing(GTK_TREE_VIEW_COLUMN(pl->length_column), GTK_TREE_VIEW_COLUMN_FIXED); ms_progress_bar_show(); pl->ms_semaphore++; aqualung_idle_add(store_addlist_iter_cb, (gpointer)add_iter); } /****************************************/ void search_cb(gpointer data) { music_store_search(); } /* mode: 0 normal, 1 album mode */ void store__addlist_with_mode(int mode, gpointer data) { GtkTreeIter iter_store; playlist_t * pl = playlist_get_current(); if (gtk_tree_selection_get_selected(music_select, NULL, &iter_store)) { store_addlist_iter(iter_store, pl, (GtkTreeIter *)data, mode); } } void store__addlist_defmode(gpointer data) { store__addlist_with_mode(options.playlist_is_tree, data); } void store__addlist_albummode_cb(gpointer data) { store__addlist_with_mode(1, data); } void store__addlist_cb(gpointer data) { store__addlist_with_mode(0, data); } void store__add_cb(gpointer user_data) { GtkTreeIter iter; char name[MAXLEN]; store_data_t * data; xmlDocPtr doc; xmlNodePtr root; name[0] = '\0'; if (add_store_dialog(name, &data)) { if (access(data->file, F_OK) == 0) { message_dialog(_("Create empty store"), browser_window, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, NULL, _("The store '%s' already exists.\nAdd it on the Settings/Music Store tab."), data->file); } else { char * utf8 = g_filename_to_utf8(data->file, -1, NULL, NULL, NULL); gtk_tree_store_append(music_store, &iter, NULL); gtk_tree_store_set(music_store, &iter, MS_COL_NAME, name, MS_COL_FONT, PANGO_WEIGHT_BOLD, MS_COL_DATA, data, -1); if (options.enable_ms_tree_icons) { gtk_tree_store_set(music_store, &iter, MS_COL_ICON, icon_store, -1); } doc = xmlNewDoc((const xmlChar *) "1.0"); root = xmlNewNode(NULL, (const xmlChar *) "music_store"); xmlDocSetRootElement(doc, root); xmlNewTextChild(root, NULL, (const xmlChar *) "name", (xmlChar *) name); if (data->comment != NULL && data->comment[0] != '\0') { xmlNewTextChild(root, NULL, (const xmlChar *) "comment", (xmlChar *) data->comment); } xmlSaveFormatFile(data->file, doc, 1); xmlFreeDoc(doc); gtk_list_store_append(ms_pathlist_store, &iter); gtk_list_store_set(ms_pathlist_store, &iter, 0, data->file, 1, utf8, 2, _("rw"), -1); g_free(utf8); } } } void store__build_cb(gpointer data) { GtkTreeIter store_iter; GtkTreeModel * model; if (gtk_tree_selection_get_selected(music_select, &model, &store_iter)) { store_data_t * data; gtk_tree_model_get(model, &store_iter, MS_COL_DATA, &data, -1); if (data->readonly) { return; } build_store(&store_iter, data->file); } } void store__edit_cb(gpointer user_data) { GtkTreeIter iter; GtkTreeModel * model; store_data_t * data; char * pname; char name[MAXLEN+1]; if (gtk_tree_selection_get_selected(music_select, &model, &iter)) { gtk_tree_model_get(model, &iter, MS_COL_NAME, &pname, MS_COL_DATA, &data, -1); if (data->readonly) { g_free(pname); return; } strncpy(name, pname, MAXLEN-1); g_free(pname); if (edit_store_dialog(name + ((data->dirty) ? 1 : 0), data)) { gtk_tree_store_set(music_store, &iter, MS_COL_NAME, name, -1); music_store_mark_changed(&iter); } } } void store_volume_calc(int unmeasured) { GtkTreeIter iter_store; GtkTreeIter iter_artist; GtkTreeIter iter_record; GtkTreeIter iter_track; GtkTreeModel * model; int h, i, j; volume_t * vol = NULL; if (gtk_tree_selection_get_selected(music_select, &model, &iter_store)) { if (is_store_iter_readonly(&iter_store)) { return; } if ((vol = volume_new(music_store, VOLUME_SEPARATE)) == NULL) { return; } h = 0; while (gtk_tree_model_iter_nth_child(model, &iter_artist, &iter_store, h++)) { i = 0; while (gtk_tree_model_iter_nth_child(model, &iter_record, &iter_artist, i++)) { j = 0; while (gtk_tree_model_iter_nth_child(model, &iter_track, &iter_record, j++)) { track_data_t * data; gtk_tree_model_get(model, &iter_track, MS_COL_DATA, &data, -1); if (!unmeasured || data->volume > 0.1f) { volume_push(vol, data->file, iter_track); } } } } volume_start(vol); } } void store__volume_unmeasured_cb(gpointer data) { store_volume_calc(1); } void store__volume_all_cb(gpointer data) { store_volume_calc(0); } void store__remove_cb(gpointer user_data) { GtkTreeIter iter; GtkTreeModel * model; store_data_t * data; char * pname; char name[MAXLEN]; char text[MAXLEN]; int i = 0; if (gtk_tree_selection_get_selected(music_select, &model, &iter)) { gtk_tree_model_get(model, &iter, MS_COL_NAME, &pname, MS_COL_DATA, &data, -1); strncpy(name, pname, MAXLEN-1); g_free(pname); snprintf(text, MAXLEN-1, _("Really remove store \"%s\" from the Music Store?"), (data->dirty) ? (name + 1) : (name)); if (confirm_dialog(_("Remove Store"), text)) { char * file = strdup(data->file); if (data->dirty) { if (confirm_dialog(_("Remove Store"), _("Do you want to save the store before removing?"))) { store_file_save(&iter); } else { music_store_mark_saved(&iter); } } if (store_file_remove_store(&iter)) { gtk_tree_selection_select_iter(music_select, &iter); } else { int last; if ((last = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(music_store), NULL))) { gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &iter, NULL, last-1); gtk_tree_selection_select_iter(music_select, &iter); } } i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(ms_pathlist_store), &iter, NULL, i++)) { gtk_tree_model_get(GTK_TREE_MODEL(ms_pathlist_store), &iter, 0, &pname, -1); if (!strcmp(file, pname)) { gtk_list_store_remove(ms_pathlist_store, &iter); } g_free(pname); } } } } void store__save_cb(gpointer data) { GtkTreeIter iter; if (gtk_tree_selection_get_selected(music_select, NULL, &iter)) { store_file_save(&iter); } } /****************************************/ /* mode: 0 normal, 1 album mode */ void artist__addlist_with_mode(int mode, gpointer data) { GtkTreeIter iter_artist; playlist_t * pl = playlist_get_current(); if (gtk_tree_selection_get_selected(music_select, NULL, &iter_artist)) { artist_addlist_iter(iter_artist, pl, (GtkTreeIter *)data, mode); } } void artist__addlist_defmode(gpointer data) { artist__addlist_with_mode(options.playlist_is_tree, data); } void artist__addlist_albummode_cb(gpointer data) { artist__addlist_with_mode(1, data); } void artist__addlist_cb(gpointer data) { artist__addlist_with_mode(0, data); } void artist__add_cb(gpointer user_data) { GtkTreeIter iter; GtkTreeIter parent_iter; GtkTreePath * parent_path; GtkTreeModel * model; artist_data_t * data; char name[MAXLEN]; char sort[MAXLEN]; name[0] = '\0'; sort[0] = '\0'; if (gtk_tree_selection_get_selected(music_select, &model, &parent_iter)) { if (is_store_iter_readonly(&parent_iter)) return; /* get iter to music store (parent) */ parent_path = gtk_tree_model_get_path(model, &parent_iter); if (gtk_tree_path_get_depth(parent_path) == 2) { gtk_tree_path_up(parent_path); } gtk_tree_model_get_iter(model, &parent_iter, parent_path); gtk_tree_path_free(parent_path); if (add_artist_dialog(name, sort, &data)) { gtk_tree_store_append(music_store, &iter, &parent_iter); gtk_tree_store_set(music_store, &iter, MS_COL_NAME, name, MS_COL_SORT, sort, MS_COL_DATA, data, -1); if (options.enable_ms_tree_icons) { gtk_tree_store_set(music_store, &iter, MS_COL_ICON, icon_artist, -1); } music_store_mark_changed(&iter); } } } void artist__edit_cb(gpointer user_data) { GtkTreeIter iter; GtkTreeModel * model; char * pname; char * psort; char name[MAXLEN]; char sort[MAXLEN]; artist_data_t * data; if (gtk_tree_selection_get_selected(music_select, &model, &iter)) { if (is_store_iter_readonly(&iter)) return; gtk_tree_model_get(model, &iter, MS_COL_NAME, &pname, MS_COL_SORT, &psort, MS_COL_DATA, &data, -1); strncpy(name, pname, MAXLEN-1); strncpy(sort, psort, MAXLEN-1); g_free(pname); g_free(psort); if (edit_artist_dialog(name, sort, data)) { gtk_tree_store_set(music_store, &iter, MS_COL_NAME, name, MS_COL_SORT, sort, -1); music_store_mark_changed(&iter); } } } void artist_volume_calc(int unmeasured) { GtkTreeIter iter_artist; GtkTreeIter iter_record; GtkTreeIter iter_track; GtkTreeModel * model; int i, j; volume_t * vol = NULL; if (gtk_tree_selection_get_selected(music_select, &model, &iter_artist)) { if (is_store_iter_readonly(&iter_artist)) { return; } if ((vol = volume_new(music_store, VOLUME_SEPARATE)) == NULL) { return; } i = 0; while (gtk_tree_model_iter_nth_child(model, &iter_record, &iter_artist, i++)) { j = 0; while (gtk_tree_model_iter_nth_child(model, &iter_track, &iter_record, j++)) { track_data_t * data; gtk_tree_model_get(model, &iter_track, MS_COL_DATA, &data, -1); if (!unmeasured || data->volume > 0.1f) { volume_push(vol, data->file, iter_track); } } } volume_start(vol); } } void artist__volume_unmeasured_cb(gpointer data) { artist_volume_calc(1); } void artist__volume_all_cb(gpointer data) { artist_volume_calc(0); } void artist__remove_cb(gpointer data) { generic_remove_cb(_("Remove Artist"), store_file_remove_artist); } /************************************/ /* mode: 0 normal, 1 album mode */ void record__addlist_with_mode(int mode, gpointer data) { GtkTreeIter iter_record; playlist_t * pl = playlist_get_current(); if (gtk_tree_selection_get_selected(music_select, NULL, &iter_record)) { record_addlist_iter(iter_record, pl, (GtkTreeIter *)data, mode); if (pl == playlist_get_current()) { playlist_content_changed(pl); } } } void record__addlist_defmode(gpointer data) { record__addlist_with_mode(options.playlist_is_tree, data); } void record__addlist_albummode_cb(gpointer data) { record__addlist_with_mode(1, data); } void record__addlist_cb(gpointer data) { record__addlist_with_mode(0, data); } void record__add_cb(gpointer user_data) { GtkTreeIter iter; GtkTreeIter parent_iter; GtkTreeIter child_iter; GtkTreePath * parent_path; GtkTreeModel * model; record_data_t * data; char name[MAXLEN]; char sort[MAXLEN]; char ** strings = NULL; char * str; char str_n[16]; int i; name[0] = '\0'; sort[0] = '\0'; if (gtk_tree_selection_get_selected(music_select, &model, &parent_iter)) { if (is_store_iter_readonly(&parent_iter)) return; /* get iter to artist (parent) */ parent_path = gtk_tree_model_get_path(model, &parent_iter); if (gtk_tree_path_get_depth(parent_path) == 3) gtk_tree_path_up(parent_path); gtk_tree_model_get_iter(model, &parent_iter, parent_path); if (add_record_dialog(name, sort, &strings, &data)) { gtk_tree_store_append(music_store, &iter, &parent_iter); gtk_tree_store_set(music_store, &iter, MS_COL_NAME, name, MS_COL_SORT, sort, MS_COL_DATA, data, -1); if (options.enable_ms_tree_icons) { gtk_tree_store_set(music_store, &iter, MS_COL_ICON, icon_record, -1); } music_store_mark_changed(&iter); if (strings) { for (i = 0; strings[i] != NULL; i++) { sprintf(str_n, "%02d", i+1); str = strings[i]; while (strstr(str, "/")) { str = strstr(str, "/") + 1; } if (str) { track_data_t * track; char * utf8 = g_filename_to_utf8(str, -1, NULL, NULL, NULL); float duration = get_file_duration(strings[i]); if ((track = (track_data_t *)calloc(1, sizeof(track_data_t))) == NULL) { fprintf(stderr, "record__add_cb: calloc error\n"); return; } track->file = strdup(strings[i]); track->duration = duration > 0.0f ? duration : 0.0f; track->volume = 1.0f; track->use_rva = 0; gtk_tree_store_append(music_store, &child_iter, &iter); gtk_tree_store_set(music_store, &child_iter, MS_COL_NAME, utf8, MS_COL_SORT, str_n, MS_COL_DATA, track, -1); if (options.enable_ms_tree_icons) { gtk_tree_store_set(music_store, &child_iter, MS_COL_ICON, icon_track, -1); } g_free(utf8); } free(strings[i]); } free(strings); } } } } void record__edit_cb(gpointer user_data) { GtkTreeIter iter; GtkTreeModel * model; record_data_t * data; char * pname; char * psort; char name[MAXLEN]; char sort[MAXLEN]; if (gtk_tree_selection_get_selected(music_select, &model, &iter)) { if (is_store_iter_readonly(&iter)) { return; } gtk_tree_model_get(model, &iter, MS_COL_NAME, &pname, MS_COL_SORT, &psort, MS_COL_DATA, &data, -1); strncpy(name, pname, MAXLEN-1); strncpy(sort, psort, MAXLEN-1); g_free(pname); g_free(psort); if (edit_record_dialog(name, sort, data)) { gtk_tree_store_set(music_store, &iter, MS_COL_NAME, name, MS_COL_SORT, sort, -1); music_store_mark_changed(&iter); } } } void record_volume_calc(int unmeasured) { GtkTreeIter iter_record; GtkTreeIter iter_track; GtkTreeModel * model; int i; volume_t * vol = NULL; if (gtk_tree_selection_get_selected(music_select, &model, &iter_record)) { if (is_store_iter_readonly(&iter_record)) { return; } if ((vol = volume_new(music_store, VOLUME_SEPARATE)) == NULL) { return; } i = 0; while (gtk_tree_model_iter_nth_child(model, &iter_track, &iter_record, i++)) { track_data_t * data; gtk_tree_model_get(model, &iter_track, MS_COL_DATA, &data, -1); if (!unmeasured || data->volume > 0.1f) { volume_push(vol, data->file, iter_track); } } } volume_start(vol); } void record__volume_unmeasured_cb(gpointer data) { record_volume_calc(1); } void record__volume_all_cb(gpointer data) { record_volume_calc(0); } void record__remove_cb(gpointer data) { generic_remove_cb(_("Remove Record"), store_file_remove_record); } #ifdef HAVE_CDDB static int cddb_init_query_data(GtkTreeIter * iter_record, int * ntracks, int ** frames, int * length) { int i; float len = 0.0f; float offset = 150.0f; /* leading 2 secs in frames */ GtkTreeIter iter_track; track_data_t * data; *ntracks = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(music_store), iter_record); if ((*frames = (int *)calloc(*ntracks, sizeof(int))) == NULL) { fprintf(stderr, "store_file.c: cddb_init_query_data: calloc error\n"); return 1; } i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &iter_track, iter_record, i)) { gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter_track, MS_COL_DATA, &data, -1); *((*frames) + i) = (int)offset; len += data->duration; offset += 75.0f * data->duration; ++i; } *length = (int)len; return 0; } void record__cddb_cb(gpointer data) { GtkTreeIter iter; if (gtk_tree_selection_get_selected(music_select, NULL, &iter) && !is_store_iter_readonly(&iter)) { int ntracks; int * frames; int length; if (cddb_init_query_data(&iter, &ntracks, &frames, &length) == 0) { cddb_start_query(&iter, ntracks, frames, length); } } } void record__cddb_submit_cb(gpointer data) { GtkTreeIter iter; if (gtk_tree_selection_get_selected(music_select, NULL, &iter) && !is_store_iter_readonly(&iter)) { int ntracks; int * frames; int length; if (cddb_init_query_data(&iter, &ntracks, &frames, &length) == 0) { cddb_start_submit(&iter, ntracks, frames, length); } } } #endif /* HAVE_CDDB */ /************************************/ void track__addlist_cb(gpointer data) { GtkTreeIter iter_track; playlist_t * pl = playlist_get_current(); if (gtk_tree_selection_get_selected(music_select, NULL, &iter_track)) { track_addlist_iter(iter_track, pl, NULL, (GtkTreeIter *)data, 0.0f, 0); if (pl == playlist_get_current()) { playlist_content_changed(pl); } } } void track__add_cb(gpointer user_data) { GtkTreeIter iter; GtkTreeIter parent_iter; GtkTreePath * parent_path; GtkTreeModel * model; track_data_t * data; char name[MAXLEN]; char sort[MAXLEN]; name[0] = '\0'; sort[0] = '\0'; if (gtk_tree_selection_get_selected(music_select, &model, &parent_iter)) { if (is_store_iter_readonly(&parent_iter)) { return; } /* get iter to artist (parent) */ parent_path = gtk_tree_model_get_path(model, &parent_iter); if (gtk_tree_path_get_depth(parent_path) == 4) { gtk_tree_path_up(parent_path); } gtk_tree_model_get_iter(model, &parent_iter, parent_path); if (add_track_dialog(name, sort, &data)) { gtk_tree_store_append(music_store, &iter, &parent_iter); gtk_tree_store_set(music_store, &iter, MS_COL_NAME, name, MS_COL_SORT, sort, MS_COL_DATA, data, -1); if (options.enable_ms_tree_icons) { gtk_tree_store_set(music_store, &iter, MS_COL_ICON, icon_track, -1); } music_store_mark_changed(&iter); } } } void track__edit_cb(gpointer user_data) { GtkTreeIter iter; GtkTreeModel * model; track_data_t * data; char * pname; char * psort; char name[MAXLEN]; char sort[MAXLEN]; if (gtk_tree_selection_get_selected(music_select, &model, &iter)) { if (is_store_iter_readonly(&iter)) { return; } gtk_tree_model_get(model, &iter, MS_COL_NAME, &pname, MS_COL_SORT, &psort, MS_COL_DATA, &data, -1); strncpy(name, pname, MAXLEN-1); strncpy(sort, psort, MAXLEN-1); g_free(pname); g_free(psort); if (edit_track_dialog(name, sort, data)) { gtk_tree_store_set(music_store, &iter, MS_COL_NAME, name, MS_COL_SORT, sort, -1); music_store_mark_changed(&iter); } } } void track__fileinfo_cb(gpointer user_data) { GtkTreeIter iter_track; GtkTreeIter iter_record; GtkTreeIter iter_artist; GtkTreeModel * model; track_data_t * data; char * ptrack_name; char * precord_name; char * partist_name; char track_name[MAXLEN]; char record_name[MAXLEN]; char artist_name[MAXLEN]; char list_str[MAXLEN]; if (gtk_tree_selection_get_selected(music_select, &model, &iter_track)) { gtk_tree_model_get(model, &iter_track, MS_COL_NAME, &ptrack_name, MS_COL_DATA, &data, -1); strncpy(track_name, ptrack_name, MAXLEN-1); g_free(ptrack_name); gtk_tree_model_iter_parent(model, &iter_record, &iter_track); gtk_tree_model_get(model, &iter_record, MS_COL_NAME, &precord_name, -1); strncpy(record_name, precord_name, MAXLEN-1); g_free(precord_name); gtk_tree_model_iter_parent(model, &iter_artist, &iter_record); gtk_tree_model_get(model, &iter_artist, MS_COL_NAME, &partist_name, -1); strncpy(artist_name, partist_name, MAXLEN-1); g_free(partist_name); make_title_string(list_str, options.title_format, artist_name, record_name, track_name); if (is_store_iter_readonly(&iter_track)) { show_file_info(list_str, data->file, 0, model, iter_track, TRUE); } else { show_file_info(list_str, data->file, 1, model, iter_track, TRUE); } } } void track_volume_calc(int unmeasured) { GtkTreeIter iter_track; GtkTreeModel * model; track_data_t * data; volume_t * vol = NULL; if (gtk_tree_selection_get_selected(music_select, &model, &iter_track)) { if (is_store_iter_readonly(&iter_track)) { return; } if ((vol = volume_new(music_store, VOLUME_SEPARATE)) == NULL) { return; } gtk_tree_model_get(model, &iter_track, MS_COL_DATA, &data, -1); if (!unmeasured || data->volume > 0.1f) { volume_push(vol, data->file, iter_track); volume_start(vol); } } } void track__volume_unmeasured_cb(gpointer data) { track_volume_calc(1); } void track__volume_all_cb(gpointer data) { track_volume_calc(0); } void track__remove_cb(gpointer data) { generic_remove_cb(_("Remove Track"), store_file_remove_track); } /************************************/ #ifdef HAVE_EXPORT void track_export(GtkTreeIter * iter_track, export_t * export, char * _artist, char * _album, int year) { GtkTreeIter iter_artist; GtkTreeIter iter_record; track_data_t * track_data; char artist[MAXLEN]; char album[MAXLEN]; char * title; char * str_no; int no = 0; gtk_tree_model_get(GTK_TREE_MODEL(music_store), iter_track, MS_COL_NAME, &title, MS_COL_SORT, &str_no, MS_COL_DATA, &track_data, -1); sscanf(str_no, "%d", &no); if (_album == NULL || _artist == NULL) { gtk_tree_model_iter_parent(GTK_TREE_MODEL(music_store), &iter_record, iter_track); } if (_album == NULL) { record_data_t * record_data; char * tmp; gtk_tree_model_iter_parent(GTK_TREE_MODEL(music_store), &iter_record, iter_track); gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter_record, MS_COL_NAME, &tmp, MS_COL_DATA, &record_data, -1); strncpy(album, tmp, MAXLEN-1); g_free(tmp); year = record_data->year; } else { strncpy(album, _album, MAXLEN-1); } if (_artist == NULL) { char * tmp; gtk_tree_model_iter_parent(GTK_TREE_MODEL(music_store), &iter_artist, &iter_record); gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter_artist, MS_COL_NAME, &tmp, -1); strncpy(artist, tmp, MAXLEN-1); g_free(tmp); } else { strncpy(artist, _artist, MAXLEN-1); } export_append_item(export, track_data->file, artist, album, title, year, no); g_free(title); g_free(str_no); } void record_export(GtkTreeIter * iter_record, export_t * export, char * _artist) { GtkTreeIter iter_artist; GtkTreeIter iter_track; char artist[MAXLEN]; char * record; record_data_t * record_data; int i; gtk_tree_model_get(GTK_TREE_MODEL(music_store), iter_record, MS_COL_NAME, &record, MS_COL_DATA, &record_data, -1); if (_artist == NULL) { char * tmp; gtk_tree_model_iter_parent(GTK_TREE_MODEL(music_store), &iter_artist, iter_record); gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter_artist, MS_COL_NAME, &tmp, -1); strncpy(artist, tmp, MAXLEN-1); g_free(tmp); } else { strncpy(artist, _artist, MAXLEN-1); } i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &iter_track, iter_record, i++)) { track_export(&iter_track, export, artist, record, record_data->year); } g_free(record); } void artist_export(GtkTreeIter * iter_artist, export_t * export) { GtkTreeIter iter_record; char * artist; int i; gtk_tree_model_get(GTK_TREE_MODEL(music_store), iter_artist, MS_COL_NAME, &artist, -1); i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &iter_record, iter_artist, i++)) { record_export(&iter_record, export, artist); } g_free(artist); } void track__export_cb(gpointer user_data) { GtkTreeIter iter_track; export_t * export; if (gtk_tree_selection_get_selected(music_select, NULL, &iter_track)) { if ((export = export_new()) == NULL) { return; } track_export(&iter_track, export, NULL, NULL, 0); export_start(export); } } void record__export_cb(gpointer user_data) { GtkTreeIter iter_record; export_t * export; if (gtk_tree_selection_get_selected(music_select, NULL, &iter_record)) { if ((export = export_new()) == NULL) { return; } record_export(&iter_record, export, NULL); export_start(export); } } void artist__export_cb(gpointer user_data) { GtkTreeIter iter_artist; export_t * export; if (gtk_tree_selection_get_selected(music_select, NULL, &iter_artist)) { if ((export = export_new()) == NULL) { return; } artist_export(&iter_artist, export); export_start(export); } } void store__export_cb(gpointer user_data) { GtkTreeIter iter_store; GtkTreeIter iter_artist; export_t * export; int i; if (gtk_tree_selection_get_selected(music_select, NULL, &iter_store)) { if ((export = export_new()) == NULL) { return; } i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &iter_artist, &iter_store, i++)) { artist_export(&iter_artist, export); } export_start(export); } } #endif /* HAVE_EXPORT */ /************************************/ AQUALUNG_THREAD_DECLARE(tag_thread_id) volatile int batch_tag_cancelled; GtkTreeIter store_tag_iter; GtkTreeIter artist_tag_iter; GtkTreeIter record_tag_iter; GtkTreeIter track_tag_iter; char artist_tag[MAXLEN]; char album_tag[MAXLEN]; char year_tag[MAXLEN]; batch_tag_t * batch_tag_curr = NULL; GtkWidget * tag_prog_window; GtkWidget * tag_prog_file_entry; GtkWidget * tag_prog_cancel_button; GtkListStore * tag_error_list; int create_tag_dialog() { GtkWidget * dialog; GtkWidget * vbox; GtkWidget * check_artist; GtkWidget * check_record; GtkWidget * check_track; GtkWidget * check_comment; GtkWidget * check_trackno; GtkWidget * check_year; dialog = gtk_dialog_new_with_buttons(_("Update file metadata"), GTK_WINDOW(browser_window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL); vbox = gtk_vbox_new(FALSE, 0); gtk_container_set_border_width(GTK_CONTAINER(vbox), 5); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), vbox, FALSE, FALSE, 0); check_artist = gtk_check_button_new_with_label(_("Artist name")); check_record = gtk_check_button_new_with_label(_("Record name")); check_track = gtk_check_button_new_with_label(_("Track name")); check_comment = gtk_check_button_new_with_label(_("Track comment")); check_trackno = gtk_check_button_new_with_label(_("Track number")); check_year = gtk_check_button_new_with_label(_("Year")); gtk_widget_set_name(check_artist, "check_on_window"); gtk_widget_set_name(check_record, "check_on_window"); gtk_widget_set_name(check_track, "check_on_window"); gtk_widget_set_name(check_comment, "check_on_window"); gtk_widget_set_name(check_trackno, "check_on_window"); gtk_widget_set_name(check_year, "check_on_window"); gtk_box_pack_start(GTK_BOX(vbox), check_artist, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox), check_record, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox), check_track, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox), check_comment, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox), check_trackno, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox), check_year, FALSE, FALSE, 0); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_artist), options.batch_tag_flags & BATCH_TAG_ARTIST); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_record), options.batch_tag_flags & BATCH_TAG_ALBUM); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_track), options.batch_tag_flags & BATCH_TAG_TITLE); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_comment), options.batch_tag_flags & BATCH_TAG_COMMENT); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_trackno), options.batch_tag_flags & BATCH_TAG_TRACKNO); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_year), options.batch_tag_flags & BATCH_TAG_YEAR); gtk_widget_show_all(dialog); if (aqualung_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { set_option_bit_from_toggle(check_artist, &options.batch_tag_flags, BATCH_TAG_ARTIST); set_option_bit_from_toggle(check_record, &options.batch_tag_flags, BATCH_TAG_ALBUM); set_option_bit_from_toggle(check_track, &options.batch_tag_flags, BATCH_TAG_TITLE); set_option_bit_from_toggle(check_comment, &options.batch_tag_flags, BATCH_TAG_COMMENT); set_option_bit_from_toggle(check_year, &options.batch_tag_flags, BATCH_TAG_YEAR); set_option_bit_from_toggle(check_trackno, &options.batch_tag_flags, BATCH_TAG_TRACKNO); if (options.batch_tag_flags) { gtk_widget_destroy(dialog); return 1; } } gtk_widget_destroy(dialog); return 0; } void tag_prog_window_close(GtkWidget * widget, gpointer data) { batch_tag_cancelled = 1; batch_tag_root = batch_tag_curr = NULL; if (tag_prog_window) { gtk_widget_destroy(tag_prog_window); tag_prog_window = NULL; } } void cancel_batch_tag(GtkWidget * widget, gpointer data) { tag_prog_window_close(NULL, NULL); } void create_tag_prog_window(void) { GtkWidget * table; GtkWidget * label; GtkWidget * vbox; GtkWidget * hbox_result; GtkWidget * label_result; GtkWidget * hbox; GtkWidget * hbuttonbox; GtkWidget * hseparator; GtkWidget * viewport; GtkWidget * scrollwin; GtkWidget * tag_error_view; GtkTreeViewColumn * column; GtkCellRenderer * renderer; tag_prog_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(tag_prog_window), _("Update file metadata")); gtk_window_set_position(GTK_WINDOW(tag_prog_window), GTK_WIN_POS_CENTER); gtk_window_resize(GTK_WINDOW(tag_prog_window), 600, 300); g_signal_connect(G_OBJECT(tag_prog_window), "delete_event", G_CALLBACK(tag_prog_window_close), NULL); gtk_container_set_border_width(GTK_CONTAINER(tag_prog_window), 20); vbox = gtk_vbox_new(FALSE, 0); gtk_container_add(GTK_CONTAINER(tag_prog_window), vbox); table = gtk_table_new(3, 2, FALSE); gtk_box_pack_start(GTK_BOX(vbox), table, TRUE, TRUE, 0); hbox = gtk_hbox_new(FALSE, 0); label = gtk_label_new(_("File:")); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 0); gtk_table_attach(GTK_TABLE(table), hbox, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 5, 5); tag_prog_file_entry = gtk_entry_new(); gtk_editable_set_editable(GTK_EDITABLE(tag_prog_file_entry), FALSE); gtk_table_attach(GTK_TABLE(table), tag_prog_file_entry, 1, 2, 0, 1, GTK_FILL | GTK_EXPAND, GTK_FILL, 5, 5); hbox_result = gtk_hbox_new(FALSE, 0); label_result = gtk_label_new(_("Failed to set metadata for the following files:")); gtk_box_pack_start(GTK_BOX(hbox_result), label_result, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(table), hbox_result, 0, 2, 1, 2, GTK_FILL, GTK_FILL, 5, 5); tag_error_list = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING); tag_error_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(tag_error_list)); gtk_tree_view_set_enable_search(GTK_TREE_VIEW(tag_error_view), FALSE); renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes(_("Filename"), renderer, "text", 0, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(tag_error_view), column); column = gtk_tree_view_column_new_with_attributes(_("Reason"), renderer, "text", 1, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(tag_error_view), column); scrollwin = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); viewport = gtk_viewport_new(NULL, NULL); gtk_table_attach(GTK_TABLE(table), viewport, 0, 2, 2, 3, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 5, 5); gtk_container_add(GTK_CONTAINER(viewport), scrollwin); gtk_container_add(GTK_CONTAINER(scrollwin), tag_error_view); hseparator = gtk_hseparator_new(); gtk_box_pack_start(GTK_BOX(vbox), hseparator, FALSE, TRUE, 5); hbuttonbox = gtk_hbutton_box_new(); gtk_box_pack_end(GTK_BOX(vbox), hbuttonbox, FALSE, TRUE, 0); gtk_button_box_set_layout(GTK_BUTTON_BOX(hbuttonbox), GTK_BUTTONBOX_END); tag_prog_cancel_button = gui_stock_label_button (_("Abort"), GTK_STOCK_CANCEL); g_signal_connect(tag_prog_cancel_button, "clicked", G_CALLBACK(cancel_batch_tag), NULL); gtk_container_add(GTK_CONTAINER(hbuttonbox), tag_prog_cancel_button); gtk_widget_grab_focus(tag_prog_cancel_button); gtk_widget_show_all(tag_prog_window); } gboolean set_tag_prog_file_entry(gpointer data) { if (tag_prog_window) { char * utf8 = g_filename_display_name((char *)data); gtk_entry_set_text(GTK_ENTRY(tag_prog_file_entry), utf8); gtk_widget_grab_focus(tag_prog_cancel_button); g_free(utf8); } return FALSE; } gboolean batch_tag_finish(gpointer data) { if (gtk_tree_model_iter_n_children(GTK_TREE_MODEL(tag_error_list), NULL) > 0) { gtk_entry_set_text(GTK_ENTRY(tag_prog_file_entry), ""); gtk_button_set_label(GTK_BUTTON(tag_prog_cancel_button), GTK_STOCK_CLOSE); gtk_button_set_use_stock(GTK_BUTTON(tag_prog_cancel_button), TRUE); } else { tag_prog_window_close(NULL, NULL); } return FALSE; } typedef struct { char * filename; int ret; } batch_tag_error_t; gboolean batch_tag_append_error(gpointer data) { batch_tag_error_t * err = (batch_tag_error_t *)data; GtkTreeIter iter; gtk_list_store_append(tag_error_list, &iter); gtk_list_store_set(tag_error_list, &iter, 0, err->filename, 1, metadata_strerror(err->ret), -1); free(err->filename); free(err); return FALSE; } void * update_tag_thread(void * args) { batch_tag_t * ptag = (batch_tag_t *)args; batch_tag_t * _ptag = ptag; AQUALUNG_THREAD_DETACH() while (ptag) { int ret; if (batch_tag_cancelled) { while (ptag) { ptag = ptag->next; free(_ptag); _ptag = ptag; } aqualung_idle_add(batch_tag_finish, NULL); return NULL; } aqualung_idle_add(set_tag_prog_file_entry, (gpointer)ptag->filename); ret = meta_update_basic(ptag->filename, (options.batch_tag_flags & BATCH_TAG_TITLE) ? ptag->title : NULL, (options.batch_tag_flags & BATCH_TAG_ARTIST) ? ptag->artist : NULL, (options.batch_tag_flags & BATCH_TAG_ALBUM) ? ptag->album : NULL, (options.batch_tag_flags & BATCH_TAG_COMMENT) ? ptag->comment : NULL, NULL /* genre */, (options.batch_tag_flags & BATCH_TAG_YEAR) ? ptag->year : NULL, (options.batch_tag_flags & BATCH_TAG_TRACKNO) ? ptag->trackno : -1); if (ret < 0) { batch_tag_error_t * err = (batch_tag_error_t *)calloc(sizeof(batch_tag_error_t), 1); if (err == NULL) { fprintf(stderr, "update_tag_thread: calloc error\n"); } else { err->filename = strdup(ptag->filename); err->ret = ret; aqualung_idle_add(batch_tag_append_error, (gpointer)err); } } ptag = ptag->next; free(_ptag); _ptag = ptag; } aqualung_idle_add(batch_tag_finish, NULL); return NULL; } gboolean track_batch_tag(gpointer data) { char * title; char * track; batch_tag_t * ptag; track_data_t * track_data; if ((ptag = (batch_tag_t *)calloc(1, sizeof(batch_tag_t))) == NULL) { fprintf(stderr, "music_store.c: track_batch_tag(): calloc error"); return FALSE; } if (batch_tag_root == NULL) { batch_tag_root = batch_tag_curr = ptag; } else { batch_tag_curr->next = ptag; batch_tag_curr = ptag; } gtk_tree_model_get(GTK_TREE_MODEL(music_store), &track_tag_iter, MS_COL_NAME, &title, MS_COL_SORT, &track, MS_COL_DATA, &track_data, -1); strncpy(ptag->artist, artist_tag, MAXLEN-1); strncpy(ptag->album, album_tag, MAXLEN-1); strncpy(ptag->year, year_tag, MAXLEN-1); strncpy(ptag->title, title, MAXLEN-1); if (sscanf(track, "%d", &ptag->trackno) < 1) { ptag->trackno = -1; } if (track_data->file != NULL) { strncpy(ptag->filename, track_data->file, MAXLEN-1); } else { ptag->filename[0] = '\0'; } if (track_data->comment != NULL) { strncpy(ptag->comment, track_data->comment, MAXLEN-1); } else { ptag->comment[0] = '\0'; } g_free(title); g_free(track); if (data) { batch_tag_cancelled = 0; create_tag_prog_window(); AQUALUNG_THREAD_CREATE(tag_thread_id, NULL, update_tag_thread, batch_tag_root) } return FALSE; } void record_batch_tag_set_from_iter(GtkTreeIter * iter) { char * str; record_data_t * data; gtk_tree_model_get(GTK_TREE_MODEL(music_store), iter, MS_COL_NAME, &str, -1); strncpy(album_tag, str, MAXLEN-1); g_free(str); gtk_tree_model_get(GTK_TREE_MODEL(music_store), iter, MS_COL_DATA, &data, -1); snprintf(year_tag, MAXLEN-1, "%d", data->year); } gboolean record_batch_tag(gpointer data) { GtkTreeIter iter_track; int i = 0; record_batch_tag_set_from_iter(&record_tag_iter); while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &iter_track, &record_tag_iter, i++)) { track_tag_iter = iter_track; track_batch_tag(NULL); } if (data) { batch_tag_cancelled = 0; create_tag_prog_window(); AQUALUNG_THREAD_CREATE(tag_thread_id, NULL, update_tag_thread, batch_tag_root) } return FALSE; } void artist_batch_tag_set_from_iter(GtkTreeIter * iter) { char * str; gtk_tree_model_get(GTK_TREE_MODEL(music_store), iter, MS_COL_NAME, &str, -1); strncpy(artist_tag, str, MAXLEN-1); g_free(str); } gboolean artist_batch_tag(gpointer data) { GtkTreeIter iter_record; int i = 0; artist_batch_tag_set_from_iter(&artist_tag_iter); while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &iter_record, &artist_tag_iter, i++)) { record_tag_iter = iter_record; record_batch_tag(NULL); } if (data) { batch_tag_cancelled = 0; create_tag_prog_window(); AQUALUNG_THREAD_CREATE(tag_thread_id, NULL, update_tag_thread, batch_tag_root) } return FALSE; } gboolean store_batch_tag(gpointer data) { GtkTreeIter iter_artist; int i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &iter_artist, &store_tag_iter, i++)) { artist_tag_iter = iter_artist; artist_batch_tag(NULL); } if (data) { batch_tag_cancelled = 0; create_tag_prog_window(); AQUALUNG_THREAD_CREATE(tag_thread_id, NULL, update_tag_thread, batch_tag_root) } return FALSE; } void track__tag_cb(gpointer data) { GtkTreeIter iter; if (gtk_tree_selection_get_selected(music_select, NULL, &iter)) { if (create_tag_dialog()) { GtkTreeIter iter_record; GtkTreeIter iter_artist; gtk_tree_model_iter_parent(GTK_TREE_MODEL(music_store), &iter_record, &iter); record_batch_tag_set_from_iter(&iter_record); gtk_tree_model_iter_parent(GTK_TREE_MODEL(music_store), &iter_artist, &iter_record); artist_batch_tag_set_from_iter(&iter_artist); track_tag_iter = iter; aqualung_idle_add(track_batch_tag, (gpointer)1); } } } void record__tag_cb(gpointer data) { GtkTreeIter iter; if (gtk_tree_selection_get_selected(music_select, NULL, &iter)) { if (create_tag_dialog()) { GtkTreeIter iter_artist; gtk_tree_model_iter_parent(GTK_TREE_MODEL(music_store), &iter_artist, &iter); artist_batch_tag_set_from_iter(&iter_artist); record_tag_iter = iter; aqualung_idle_add(record_batch_tag, (gpointer)1); } } } void artist__tag_cb(gpointer data) { GtkTreeIter iter; if (gtk_tree_selection_get_selected(music_select, NULL, &iter)) { if (create_tag_dialog()) { artist_tag_iter = iter; aqualung_idle_add(artist_batch_tag, (gpointer)1); } } } void store__tag_cb(gpointer data) { GtkTreeIter iter; if (gtk_tree_selection_get_selected(music_select, NULL, &iter)) { if (create_tag_dialog()) { store_tag_iter = iter; aqualung_idle_add(store_batch_tag, (gpointer)1); } } } /************************************/ static void set_comment_text(GtkTreeIter * tree_iter, GtkTextIter * text_iter, GtkTextBuffer * buffer) { char * comment = NULL; void * data; GtkTreePath * path; int level; path = gtk_tree_model_get_path(GTK_TREE_MODEL(music_store), tree_iter); level = gtk_tree_path_get_depth(path); gtk_tree_path_free(path); gtk_tree_model_get(GTK_TREE_MODEL(music_store), tree_iter, MS_COL_DATA, &data, -1); switch (level) { case 1: comment = ((store_data_t *)data)->comment; break; case 2: comment = ((artist_data_t *)data)->comment; break; case 3: comment = ((record_data_t *)data)->comment; break; case 4: comment = ((track_data_t *)data)->comment; break; } if (comment != NULL && comment[0] != '\0') { gtk_text_buffer_insert(buffer, text_iter, comment, -1); } else { gtk_text_buffer_insert(buffer, text_iter, _("(no comment)"), -1); } } static void track_status_bar_info(GtkTreeModel * model, GtkTreeIter * iter, double * size, float * length) { track_data_t * data; gtk_tree_model_get(model, iter, MS_COL_DATA, &data, -1); if (data->size == 0) { struct stat statbuf; if (stat(data->file, &statbuf) != -1) { data->size = statbuf.st_size; } } *size += data->size / 1024.0; *length += data->duration; } static void record_status_bar_info(GtkTreeModel * model, GtkTreeIter * iter, double * size, float * length, int * ntrack) { GtkTreeIter track_iter; int i = 0; while (gtk_tree_model_iter_nth_child(model, &track_iter, iter, i++)) { track_status_bar_info(model, &track_iter, size, length); } *ntrack += i - 1; } static void artist_status_bar_info(GtkTreeModel * model, GtkTreeIter * iter, double * size, float * length, int * ntrack, int * nrecord) { GtkTreeIter record_iter; int i = 0; while (gtk_tree_model_iter_nth_child(model, &record_iter, iter, i++)) { record_status_bar_info(model, &record_iter, size, length, ntrack); } *nrecord += i - 1; } void store_status_bar_info(GtkTreeModel * model, GtkTreeIter * iter, double * size, float * length, int * ntrack, int * nrecord, int * nartist) { GtkTreeIter artist_iter; int i = 0; while (gtk_tree_model_iter_nth_child(model, &artist_iter, iter, i++)) { artist_status_bar_info(model, &artist_iter, size, length, ntrack, nrecord); } *nartist = i - 1; } static void set_status_bar_info(GtkTreeIter * tree_iter, GtkLabel * statusbar) { int ntrack = 0, nrecord = 0, nartist = 0; float length = 0.0f; double size = 0.0; store_data_t * store_data; record_data_t * record_data; char str[MAXLEN]; char length_str[MAXLEN]; char tmp[MAXLEN]; char * name; GtkTreeModel * model = GTK_TREE_MODEL(music_store); GtkTreePath * path; int depth; path = gtk_tree_model_get_path(model, tree_iter); depth = gtk_tree_path_get_depth(path); gtk_tree_path_free(path); gtk_tree_model_get(model, tree_iter, MS_COL_NAME, &name, -1); switch (depth) { case 4: track_status_bar_info(model, tree_iter, &size, &length); ntrack = 1; sprintf(str, "%s ", name); break; case 3: gtk_tree_model_get(model, tree_iter, MS_COL_DATA, &record_data, -1); record_status_bar_info(model, tree_iter, &size, &length, &ntrack); if (is_valid_year(record_data->year)) { sprintf(str, "%s (%d): %d %s ", name, record_data->year, ntrack, (ntrack == 1) ? _("track") : _("tracks")); } else { sprintf(str, "%s: %d %s ", name, ntrack, (ntrack == 1) ? _("track") : _("tracks")); } break; case 2: artist_status_bar_info(model, tree_iter, &size, &length, &ntrack, &nrecord); sprintf(str, "%s: %d %s, %d %s ", name, nrecord, (nrecord == 1) ? _("record") : _("records"), ntrack, (ntrack == 1) ? _("track") : _("tracks")); break; case 1: gtk_tree_model_get(model, tree_iter, MS_COL_DATA, &store_data, -1); store_status_bar_info(model, tree_iter, &size, &length, &ntrack, &nrecord, &nartist); sprintf(str, "%s: %d %s, %d %s, %d %s ", store_data->dirty ? name+1 : name, nartist, (nartist == 1) ? _("artist") : _("artists"), nrecord, (nrecord == 1) ? _("record") : _("records"), ntrack, (ntrack == 1) ? _("track") : _("tracks")); break; } g_free(name); if (length > 0.0f || ntrack == 0) { time2time(length, length_str); sprintf(tmp, " [%s] ", length_str); } else { strcpy(tmp, " [N/A] "); } strcat(str, tmp); if (options.ms_statusbar_show_size) { if (size > 1024 * 1024) { sprintf(tmp, " (%.1f GB) ", size / (1024 * 1024)); } else if (size > 1024) { sprintf(tmp, " (%.1f MB) ", size / 1024); } else if (size > 0 || ntrack == 0) { sprintf(tmp, " (%.1f KB) ", size); } else { strcpy(tmp, " (N/A) "); } strcat(str, tmp); } gtk_label_set_text(statusbar, str); } /*********************************************************************************/ /* If a non-absolute filename is in the store, interpret it as * relative to the directory containing the store file. Otherwise, * just return the absolute filename as found in the store file. */ char * track_get_absolute_path(char * store_dirname, char * filename, const GtkTreeIter * iter_track) { char * path = NULL; gchar * tmp = NULL; if (((tmp = g_filename_from_uri(filename, NULL, NULL)) == NULL) && (tmp = g_filename_from_utf8(filename, -1, NULL, NULL, NULL)) == NULL) { tmp = g_strdup(filename); } if (g_path_is_absolute(tmp)) { path = strndup(tmp, MAXLEN-1); } else { gchar * tmppath = g_build_filename(store_dirname, tmp, NULL); path = strndup(tmppath, MAXLEN-1); g_free(tmppath); } g_free(tmp); return path; } void parse_track(xmlDocPtr doc, xmlNodePtr cur, GtkTreeIter * iter_record, char * store_dirname, int * save) { GtkTreeIter iter_track; xmlChar * key; char name[MAXLEN]; char sort[MAXLEN]; track_data_t * data; name[0] = '\0'; sort[0] = '\0'; if ((data = (track_data_t *)calloc(1, sizeof(track_data_t))) == NULL) { fprintf(stderr, "parse_track: calloc error\n"); return; } gtk_tree_store_append(music_store, &iter_track, iter_record); gtk_tree_store_set(music_store, &iter_track, MS_COL_NAME, "", MS_COL_SORT, "", MS_COL_DATA, data, -1); if (options.enable_ms_tree_icons) { gtk_tree_store_set(music_store, &iter_track, MS_COL_ICON, icon_track, -1); } data->duration = 0.0f; data->volume = 1.0f; data->rva = 0.0f; data->use_rva = 0; for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) { if ((!xmlStrcmp(cur->name, (const xmlChar *)"name"))) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); if (key != NULL) { strncpy(name, (char *) key, MAXLEN-1); xmlFree(key); } if (name[0] == '\0') { fprintf(stderr, "Error in XML music_store: track is required, but NULL\n"); } gtk_tree_store_set(music_store, &iter_track, MS_COL_NAME, name, -1); } else if ((!xmlStrcmp(cur->name, (const xmlChar *)"sort_name"))) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); if (key != NULL) { strncpy(sort, (char *) key, MAXLEN-1); xmlFree(key); } gtk_tree_store_set(music_store, &iter_track, MS_COL_SORT, sort, -1); } else if ((!xmlStrcmp(cur->name, (const xmlChar *)"file"))) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); if (key != NULL) { if (httpc_is_url((char *)key)) { data->file = strndup((char *)key, MAXLEN-1); } else { data->file = track_get_absolute_path(store_dirname, (char *)key, &iter_track); } xmlFree(key); } } else if ((!xmlStrcmp(cur->name, (const xmlChar *)"size"))) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); if (key != NULL) { sscanf((char *)key, "%u", &data->size); xmlFree(key); } } else if ((!xmlStrcmp(cur->name, (const xmlChar *)"comment"))) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); if (key != NULL) { data->comment = strndup((char *)key, MAXLEN-1); xmlFree(key); } } else if ((!xmlStrcmp(cur->name, (const xmlChar *)"duration"))) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); if (key != NULL) { data->duration = convf((char *) key); xmlFree(key); } } else if ((!xmlStrcmp(cur->name, (const xmlChar *)"volume"))) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); if (key != NULL) { data->volume = convf((char *) key); xmlFree(key); } } else if ((!xmlStrcmp(cur->name, (const xmlChar *)"rva"))) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); if (key != NULL) { data->rva = convf((char *) key); xmlFree(key); } } else if ((!xmlStrcmp(cur->name, (const xmlChar *)"use_rva"))) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); if (key != NULL) { data->use_rva = convf((char *) key); xmlFree(key); } } } if (data->size == 0) { struct stat statbuf; if (stat(data->file, &statbuf) != -1) { data->size = statbuf.st_size; *save = 1; } } if (data->file == NULL) { fprintf(stderr, "Error in XML music_store: track is required, but NULL\n"); store_file_remove_track(&iter_track); } } void parse_record(xmlDocPtr doc, xmlNodePtr cur, GtkTreeIter * iter_artist, char * store_dirname, int * save) { GtkTreeIter iter_record; xmlChar * key; char name[MAXLEN]; char sort[MAXLEN]; char comment[MAXLEN]; record_data_t * data; name[0] = '\0'; sort[0] = '\0'; comment[0] = '\0'; if ((data = (record_data_t *)calloc(1, sizeof(record_data_t))) == NULL) { fprintf(stderr, "parse_record: calloc error\n"); return; } gtk_tree_store_append(music_store, &iter_record, iter_artist); gtk_tree_store_set(music_store, &iter_record, MS_COL_NAME, "", MS_COL_SORT, "", MS_COL_DATA, data, -1); if (options.enable_ms_tree_icons) { gtk_tree_store_set(music_store, &iter_record, MS_COL_ICON, icon_record, -1); } for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) { if ((!xmlStrcmp(cur->name, (const xmlChar *)"name"))) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); if (key != NULL) { strncpy(name, (char *) key, MAXLEN-1); xmlFree(key); } if (name[0] == '\0') { fprintf(stderr, "Error in XML music_store: " "Record is required, but NULL\n"); } gtk_tree_store_set(music_store, &iter_record, MS_COL_NAME, name, -1); } else if ((!xmlStrcmp(cur->name, (const xmlChar *)"sort_name"))) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); if (key != NULL) { strncpy(sort, (char *) key, MAXLEN-1); /* parse year from sort key if otherwise not set */ if (is_valid_year(atoi(sort)) && !is_valid_year(data->year)) { data->year = atoi(sort); } xmlFree(key); } gtk_tree_store_set(music_store, &iter_record, MS_COL_SORT, sort, -1); } else if ((!xmlStrcmp(cur->name, (const xmlChar *)"comment"))) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); if (key != NULL) { data->comment = strndup((char *)key, MAXLEN-1); xmlFree(key); } } else if ((!xmlStrcmp(cur->name, (const xmlChar *)"year"))) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); if (key != NULL) { data->year = atoi((char *)key); xmlFree(key); } } else if ((!xmlStrcmp(cur->name, (const xmlChar *)"track"))) { parse_track(doc, cur, &iter_record, store_dirname, save); } } } void parse_artist(xmlDocPtr doc, xmlNodePtr cur, GtkTreeIter * iter_store, char * store_dirname, int * save) { GtkTreeIter iter_artist; xmlChar * key; char name[MAXLEN]; char sort[MAXLEN]; char comment[MAXLEN]; artist_data_t * data; name[0] = '\0'; sort[0] = '\0'; comment[0] = '\0'; if ((data = (artist_data_t *)calloc(1, sizeof(artist_data_t))) == NULL) { fprintf(stderr, "parse_artist: calloc error\n"); return; } gtk_tree_store_append(music_store, &iter_artist, iter_store); gtk_tree_store_set(music_store, &iter_artist, MS_COL_NAME, "", MS_COL_SORT, "", MS_COL_DATA, data, -1); if (options.enable_ms_tree_icons) { gtk_tree_store_set(music_store, &iter_artist, MS_COL_ICON, icon_artist, -1); } for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) { if ((!xmlStrcmp(cur->name, (const xmlChar *)"name"))) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); if (key != NULL) { strncpy(name, (char *) key, MAXLEN-1); xmlFree(key); } if (name[0] == '\0') { fprintf(stderr, "Error in XML music_store: " "Artist is required, but NULL\n"); } gtk_tree_store_set(music_store, &iter_artist, MS_COL_NAME, name, -1); } else if ((!xmlStrcmp(cur->name, (const xmlChar *)"sort_name"))) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); if (key != NULL) { strncpy(sort, (char *) key, MAXLEN-1); xmlFree(key); } gtk_tree_store_set(music_store, &iter_artist, MS_COL_SORT, sort, -1); } else if ((!xmlStrcmp(cur->name, (const xmlChar *)"comment"))) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); if (key != NULL) { data->comment = strndup((char *)key, MAXLEN-1); xmlFree(key); } } else if ((!xmlStrcmp(cur->name, (const xmlChar *)"record"))) { parse_record(doc, cur, &iter_artist, store_dirname, save); } } } void store_file_load(char * store_file, char * sort) { GtkTreeIter iter_store; char name[MAXLEN]; char comment[MAXLEN]; name[0] = '\0'; comment[0] = '\0'; xmlDocPtr doc; xmlNodePtr cur; xmlChar * key; char * store_dirname; int save = 0; store_data_t * data; if (access(store_file, R_OK) != 0) { return; } doc = xmlParseFile(store_file); if (doc == NULL) { fprintf(stderr, "An XML error occured while parsing %s\n", store_file); return; } cur = xmlDocGetRootElement(doc); if (cur == NULL) { fprintf(stderr, "store_file_load: empty XML document\n"); xmlFreeDoc(doc); return; } if (xmlStrcmp(cur->name, (const xmlChar *)"music_store")) { fprintf(stderr, "store_file_load: XML document of the wrong type, " "root node != music_store\n"); xmlFreeDoc(doc); return; } if ((data = (store_data_t *)calloc(1, sizeof(store_data_t))) == NULL) { fprintf(stderr, "store_file_load: calloc error\n"); return; } data->type = STORE_TYPE_FILE; data->file = strdup(store_file); data->use_relative_paths = 0; store_dirname = g_path_get_dirname(data->file); if (access(store_file, W_OK) == 0) { data->readonly = 0; } else { data->readonly = 1; } gtk_tree_store_append(music_store, &iter_store, NULL); gtk_tree_store_set(music_store, &iter_store, MS_COL_NAME, _("Music Store"), MS_COL_SORT, sort, MS_COL_FONT, PANGO_WEIGHT_BOLD, MS_COL_DATA, data, -1); if (options.enable_ms_tree_icons) { gtk_tree_store_set(music_store, &iter_store, MS_COL_ICON, icon_store, -1); } for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) { if ((!xmlStrcmp(cur->name, (const xmlChar *)"name"))) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); if (key != NULL) { strncpy(name, (char *) key, MAXLEN-1); xmlFree(key); } if (name[0] == '\0') { fprintf(stderr, "Error in XML music_store: " "Music Store is required, but NULL\n"); } gtk_tree_store_set(music_store, &iter_store, MS_COL_NAME, name, -1); } else if ((!xmlStrcmp(cur->name, (const xmlChar *)"comment"))) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); if (key != NULL) { data->comment = strndup((char *)key, MAXLEN-1); xmlFree(key); } } else if ((!xmlStrcmp(cur->name, (const xmlChar *)"use_relative_paths"))) { data->use_relative_paths = 1; } else if ((!xmlStrcmp(cur->name, (const xmlChar *)"artist"))) { parse_artist(doc, cur, &iter_store, store_dirname, &save); } } xmlFreeDoc(doc); g_free(store_dirname); if (save && !data->readonly) { music_store_mark_changed(&iter_store); store_file_save(&iter_store); } if (options.autoexpand_stores) { GtkTreePath * path = gtk_tree_model_get_path(GTK_TREE_MODEL(music_store), &iter_store); gtk_tree_view_expand_row(GTK_TREE_VIEW(music_tree), path, FALSE); gtk_tree_path_free(path); } } /**********************************************************************************/ void save_track(xmlDocPtr doc, xmlNodePtr node_track, GtkTreeIter * iter_track, char * store_dirname, int dirname_strlen, int use_relative_paths) { xmlNodePtr node; char * name; char * sort; track_data_t * data; char str[32]; gtk_tree_model_get(GTK_TREE_MODEL(music_store), iter_track, MS_COL_NAME, &name, MS_COL_SORT, &sort, MS_COL_DATA, &data, -1); node = xmlNewTextChild(node_track, NULL, (const xmlChar *) "track", NULL); if (name[0] == '\0') { fprintf(stderr, "saving music_store XML: warning: track node with empty \n"); } xmlNewTextChild(node, NULL, (const xmlChar *) "name", (const xmlChar *) name); if (sort[0] != '\0') { xmlNewTextChild(node, NULL, (const xmlChar *) "sort_name", (const xmlChar *) sort); } if (data->file == NULL && data->file[0] != '\0') { fprintf(stderr, "saving music_store XML: warning: track node with empty \n"); xmlNewTextChild(node, NULL, (const xmlChar *) "file", (const xmlChar *) ""); } else { if (httpc_is_url(data->file)) { gchar * tmp = g_filename_to_utf8(data->file, -1, NULL, NULL, NULL); xmlNewTextChild(node, NULL, (const xmlChar *) "file", (const xmlChar *) tmp); g_free(tmp); } else if (use_relative_paths && g_str_has_prefix(data->file, store_dirname)) { gchar * tmp = data->file + dirname_strlen + 1; xmlNewTextChild(node, NULL, (const xmlChar *) "file", (const xmlChar *) tmp); } else { gchar * tmp = g_filename_to_uri(data->file, NULL, NULL); xmlNewTextChild(node, NULL, (const xmlChar *) "file", (const xmlChar *) tmp); g_free(tmp); } } if (data->size != 0) { snprintf(str, 31, "%u", data->size); xmlNewTextChild(node, NULL, (const xmlChar *) "size", (const xmlChar *) str); } if (data->comment != NULL && data->comment[0] != '\0') { xmlNewTextChild(node, NULL, (const xmlChar *) "comment", (const xmlChar *) data->comment); } if (data->duration != 0.0f) { snprintf(str, 31, "%.1f", data->duration); xmlNewTextChild(node, NULL, (const xmlChar *) "duration", (const xmlChar *) str); } if (data->volume <= 0.1f) { snprintf(str, 31, "%.1f", data->volume); xmlNewTextChild(node, NULL, (const xmlChar *) "volume", (const xmlChar *) str); } if (data->rva != 0.0f) { snprintf(str, 31, "%.1f", data->rva); xmlNewTextChild(node, NULL, (const xmlChar *) "rva", (const xmlChar *) str); } if (data->use_rva) { snprintf(str, 31, "%d", data->use_rva); xmlNewTextChild(node, NULL, (const xmlChar *) "use_rva", (const xmlChar *) str); } g_free(name); g_free(sort); } void save_record(xmlDocPtr doc, xmlNodePtr node_record, GtkTreeIter * iter_record, char * store_dirname, int dirname_strlen, int use_relative_paths) { xmlNodePtr node; char * name; char * sort; record_data_t * data; GtkTreeIter iter_track; int i = 0; gtk_tree_model_get(GTK_TREE_MODEL(music_store), iter_record, MS_COL_NAME, &name, MS_COL_SORT, &sort, MS_COL_DATA, &data, -1); node = xmlNewTextChild(node_record, NULL, (const xmlChar *) "record", NULL); if (name[0] == '\0') { fprintf(stderr, "saving music_store XML: warning: record node with empty \n"); } xmlNewTextChild(node, NULL, (const xmlChar *) "name", (const xmlChar *) name); if (sort[0] != '\0') { xmlNewTextChild(node, NULL, (const xmlChar *) "sort_name", (const xmlChar *) sort); } if (data->comment != NULL && data->comment[0] != '\0') { xmlNewTextChild(node, NULL, (const xmlChar *) "comment", (const xmlChar *) data->comment); } if (data->year != 0) { char str[32]; snprintf(str, 31, "%d", data->year); xmlNewTextChild(node, NULL, (const xmlChar *) "year", (const xmlChar *) str); } i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &iter_track, iter_record, i++)) { save_track(doc, node, &iter_track, store_dirname, dirname_strlen, use_relative_paths); } g_free(name); g_free(sort); } void save_artist(xmlDocPtr doc, xmlNodePtr root, GtkTreeIter * iter_artist, char * store_dirname, int dirname_strlen, int use_relative_paths) { xmlNodePtr node; char * name; char * sort; artist_data_t * data; GtkTreeIter iter_record; int i = 0; gtk_tree_model_get(GTK_TREE_MODEL(music_store), iter_artist, MS_COL_NAME, &name, MS_COL_SORT, &sort, MS_COL_DATA, &data, -1); node = xmlNewTextChild(root, NULL, (const xmlChar *) "artist", NULL); if (name[0] == '\0') { fprintf(stderr, "saving music_store XML: warning: artist node with empty \n"); } xmlNewTextChild(node, NULL, (const xmlChar *) "name", (const xmlChar *) name); if (sort[0] != '\0') { xmlNewTextChild(node, NULL, (const xmlChar *) "sort_name", (const xmlChar *) sort); } if (data->comment != NULL && data->comment[0] != '\0') { xmlNewTextChild(node, NULL, (const xmlChar *) "comment", (const xmlChar *) data->comment); } i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &iter_record, iter_artist, i++)) { save_record(doc, node, &iter_record, store_dirname, dirname_strlen, use_relative_paths); } g_free(name); g_free(sort); } void store_file_save(GtkTreeIter * iter_store) { xmlDocPtr doc; xmlNodePtr root; xmlNodePtr build_node; char * store_dirname; int dirname_strlen; char * name; int i; store_data_t * data; GtkTreeIter iter_artist; gtk_tree_model_get(GTK_TREE_MODEL(music_store), iter_store, MS_COL_DATA, &data, -1); if (!data->dirty) { return; } if (access(data->file, W_OK) != 0) { message_dialog(_("Warning"), browser_window, GTK_MESSAGE_WARNING, GTK_BUTTONS_CLOSE, NULL, _("File \"%s\" does not exist or your write permission has been withdrawn. " "Check if the partition containing the store file has been unmounted."), data->file); return; } music_store_mark_saved(iter_store); store_dirname = g_path_get_dirname(data->file); dirname_strlen = strlen(store_dirname); doc = xmlNewDoc((const xmlChar *) "1.0"); root = xmlNewNode(NULL, (const xmlChar *) "music_store"); xmlDocSetRootElement(doc, root); gtk_tree_model_get(GTK_TREE_MODEL(music_store), iter_store, MS_COL_NAME, &name, -1); if (name[0] == '\0') { fprintf(stderr, "saving music_store XML: warning: empty \n"); } xmlNewTextChild(root, NULL, (const xmlChar *) "name", (const xmlChar *) name); g_free(name); if (data->comment != NULL && data->comment[0] != '\0') { xmlNewTextChild(root, NULL, (const xmlChar *) "comment", (const xmlChar *) data->comment); } if (data->use_relative_paths) { xmlNewChild(root, NULL, (const xmlChar *) "use_relative_paths", NULL); } i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &iter_artist, iter_store, i++)) { save_artist(doc, root, &iter_artist, store_dirname, dirname_strlen, data->use_relative_paths); } if ((build_node = build_store_get_xml_node(data->file)) != NULL) { xmlAddChild(root, build_node); } xmlSaveFormatFile(data->file, doc, 1); xmlFreeDoc(doc); g_free(store_dirname); } /*************************************************/ /* music store interface */ int store_file_iter_is_track(GtkTreeIter * iter) { GtkTreePath * p = gtk_tree_model_get_path(GTK_TREE_MODEL(music_store), iter); int ret = (gtk_tree_path_get_depth(p) == 4); gtk_tree_path_free(p); return ret; } void store_file_iter_addlist_defmode(GtkTreeIter * ms_iter, GtkTreeIter * pl_iter, int new_tab) { GtkTreePath * p = gtk_tree_model_get_path(GTK_TREE_MODEL(music_store), ms_iter); add_path_to_playlist(p, pl_iter, new_tab); gtk_tree_path_free(p); } void store_file_selection_changed(GtkTreeIter * tree_iter, GtkTextBuffer * buffer, GtkLabel * statusbar) { GtkTextIter text_iter; gtk_text_buffer_get_iter_at_offset(buffer, &text_iter, 0); insert_cover(tree_iter, &text_iter, buffer); set_comment_text(tree_iter, &text_iter, buffer); if (options.enable_mstore_statusbar) { set_status_bar_info(tree_iter, statusbar); } } gboolean store_file_event_cb(GdkEvent * event, GtkTreeIter * iter, GtkTreePath * path) { if (event->type == GDK_BUTTON_PRESS) { GdkEventButton * bevent = (GdkEventButton *)event; if (bevent->button == 3) { set_popup_sensitivity(path); switch (gtk_tree_path_get_depth(path)) { case 1: gtk_menu_popup(GTK_MENU(store_menu), NULL, NULL, NULL, NULL, bevent->button, bevent->time); break; case 2: gtk_menu_popup(GTK_MENU(artist_menu), NULL, NULL, NULL, NULL, bevent->button, bevent->time); break; case 3: gtk_menu_popup(GTK_MENU(record_menu), NULL, NULL, NULL, NULL, bevent->button, bevent->time); break; case 4: gtk_menu_popup(GTK_MENU(track_menu), NULL, NULL, NULL, NULL, bevent->button, bevent->time); break; } } } if (event->type == GDK_KEY_PRESS) { GdkEventKey * kevent = (GdkEventKey *) event; int i; switch (gtk_tree_path_get_depth(path)) { case 1: for (i = 0; store_keybinds[i].callback; ++i) { if ((store_keybinds[i].state == 0 && kevent->state == 0) || store_keybinds[i].state & kevent->state) { if (kevent->keyval == store_keybinds[i].keyval1 || kevent->keyval == store_keybinds[i].keyval2) { (store_keybinds[i].callback)(NULL); } } } break; case 2: for (i = 0; artist_keybinds[i].callback; ++i) { if ((artist_keybinds[i].state == 0 && kevent->state == 0) || artist_keybinds[i].state & kevent->state) { if (kevent->keyval == artist_keybinds[i].keyval1 || kevent->keyval == artist_keybinds[i].keyval2) { (artist_keybinds[i].callback)(NULL); } } } break; case 3: for (i = 0; record_keybinds[i].callback; ++i) { if ((record_keybinds[i].state == 0 && kevent->state == 0) || record_keybinds[i].state & kevent->state) { if (kevent->keyval == record_keybinds[i].keyval1 || kevent->keyval == record_keybinds[i].keyval2) { (record_keybinds[i].callback)(NULL); } } } break; case 4: for (i = 0; track_keybinds[i].callback; ++i) { if ((track_keybinds[i].state == 0 && kevent->state == 0) || track_keybinds[i].state & kevent->state) { if (kevent->keyval == track_keybinds[i].keyval1 || kevent->keyval == track_keybinds[i].keyval2) { (track_keybinds[i].callback)(NULL); } } } break; } } return FALSE; } void store_file_load_icons(void) { char path[MAXLEN]; sprintf(path, "%s/%s", AQUALUNG_DATADIR, "ms-artist.png"); icon_artist = gdk_pixbuf_new_from_file (path, NULL); sprintf(path, "%s/%s", AQUALUNG_DATADIR, "ms-record.png"); icon_record = gdk_pixbuf_new_from_file (path, NULL); sprintf(path, "%s/%s", AQUALUNG_DATADIR, "ms-track.png"); icon_track = gdk_pixbuf_new_from_file (path, NULL); } void store_file_create_popup_menu(void) { /* create popup menu for music store tree items */ store_menu = gtk_menu_new(); register_toplevel_window(store_menu, TOP_WIN_SKIN); store__addlist = gtk_menu_item_new_with_label(_("Add to playlist")); store__addlist_albummode = gtk_menu_item_new_with_label(_("Add to playlist (Album mode)")); store__separator1 = gtk_separator_menu_item_new(); store__add = gtk_menu_item_new_with_label(_("Create empty store...")); store__build = gtk_menu_item_new_with_label(_("Build / Update store from filesystem...")); store__edit = gtk_menu_item_new_with_label(_("Edit store...")); #ifdef HAVE_EXPORT store__export = gtk_menu_item_new_with_label(_("Export store...")); #endif /* HAVE_EXPORT */ store__save = gtk_menu_item_new_with_label(_("Save store")); store__remove = gtk_menu_item_new_with_label(_("Remove store")); store__separator2 = gtk_separator_menu_item_new(); store__addart = gtk_menu_item_new_with_label(_("Add new artist to this store...")); store__separator3 = gtk_separator_menu_item_new(); store__volume = gtk_menu_item_new_with_label(_("Calculate volume (recursive)")); store__volume_menu = gtk_menu_new(); store__volume_unmeasured = gtk_menu_item_new_with_label(_("Unmeasured tracks only")); store__volume_all = gtk_menu_item_new_with_label(_("All tracks")); store__tag = gtk_menu_item_new_with_label(_("Batch-update file metadata...")); store__search = gtk_menu_item_new_with_label(_("Search...")); gtk_menu_shell_append(GTK_MENU_SHELL(store_menu), store__addlist); gtk_menu_shell_append(GTK_MENU_SHELL(store_menu), store__addlist_albummode); gtk_menu_shell_append(GTK_MENU_SHELL(store_menu), store__separator1); gtk_menu_shell_append(GTK_MENU_SHELL(store_menu), store__add); gtk_menu_shell_append(GTK_MENU_SHELL(store_menu), store__build); gtk_menu_shell_append(GTK_MENU_SHELL(store_menu), store__edit); #ifdef HAVE_EXPORT gtk_menu_shell_append(GTK_MENU_SHELL(store_menu), store__export); #endif /* HAVE_EXPORT */ gtk_menu_shell_append(GTK_MENU_SHELL(store_menu), store__save); gtk_menu_shell_append(GTK_MENU_SHELL(store_menu), store__remove); gtk_menu_shell_append(GTK_MENU_SHELL(store_menu), store__separator2); gtk_menu_shell_append(GTK_MENU_SHELL(store_menu), store__addart); gtk_menu_shell_append(GTK_MENU_SHELL(store_menu), store__separator3); gtk_menu_shell_append(GTK_MENU_SHELL(store_menu), store__volume); gtk_menu_item_set_submenu(GTK_MENU_ITEM(store__volume), store__volume_menu); gtk_menu_shell_append(GTK_MENU_SHELL(store__volume_menu), store__volume_unmeasured); gtk_menu_shell_append(GTK_MENU_SHELL(store__volume_menu), store__volume_all); gtk_menu_shell_append(GTK_MENU_SHELL(store_menu), store__tag); gtk_menu_shell_append(GTK_MENU_SHELL(store_menu), store__search); g_signal_connect_swapped(G_OBJECT(store__addlist), "activate", G_CALLBACK(store__addlist_cb), NULL); g_signal_connect_swapped(G_OBJECT(store__addlist_albummode), "activate", G_CALLBACK(store__addlist_albummode_cb), NULL); g_signal_connect_swapped(G_OBJECT(store__add), "activate", G_CALLBACK(store__add_cb), NULL); g_signal_connect_swapped(G_OBJECT(store__build), "activate", G_CALLBACK(store__build_cb), NULL); g_signal_connect_swapped(G_OBJECT(store__edit), "activate", G_CALLBACK(store__edit_cb), NULL); #ifdef HAVE_EXPORT g_signal_connect_swapped(G_OBJECT(store__export), "activate", G_CALLBACK(store__export_cb), NULL); #endif /* HAVE_EXPORT */ g_signal_connect_swapped(G_OBJECT(store__save), "activate", G_CALLBACK(store__save_cb), NULL); g_signal_connect_swapped(G_OBJECT(store__remove), "activate", G_CALLBACK(store__remove_cb), NULL); g_signal_connect_swapped(G_OBJECT(store__addart), "activate", G_CALLBACK(artist__add_cb), NULL); g_signal_connect_swapped(G_OBJECT(store__volume_unmeasured), "activate", G_CALLBACK(store__volume_unmeasured_cb), NULL); g_signal_connect_swapped(G_OBJECT(store__volume_all), "activate", G_CALLBACK(store__volume_all_cb), NULL); g_signal_connect_swapped(G_OBJECT(store__tag), "activate", G_CALLBACK(store__tag_cb), NULL); g_signal_connect_swapped(G_OBJECT(store__search), "activate", G_CALLBACK(search_cb), NULL); gtk_widget_show(store__addlist); gtk_widget_show(store__addlist_albummode); gtk_widget_show(store__separator1); gtk_widget_show(store__add); gtk_widget_show(store__build); gtk_widget_show(store__edit); #ifdef HAVE_EXPORT gtk_widget_show(store__export); #endif /* HAVE_EXPORT */ gtk_widget_show(store__save); gtk_widget_show(store__remove); gtk_widget_show(store__separator2); gtk_widget_show(store__addart); gtk_widget_show(store__separator3); gtk_widget_show(store__volume); gtk_widget_show(store__volume_unmeasured); gtk_widget_show(store__volume_all); gtk_widget_show(store__tag); gtk_widget_show(store__search); /* create popup menu for artist tree items */ artist_menu = gtk_menu_new(); register_toplevel_window(artist_menu, TOP_WIN_SKIN); artist__addlist = gtk_menu_item_new_with_label(_("Add to playlist")); artist__addlist_albummode = gtk_menu_item_new_with_label(_("Add to playlist (Album mode)")); artist__separator1 = gtk_separator_menu_item_new(); artist__add = gtk_menu_item_new_with_label(_("Add new artist...")); artist__edit = gtk_menu_item_new_with_label(_("Edit artist...")); #ifdef HAVE_EXPORT artist__export = gtk_menu_item_new_with_label(_("Export artist...")); #endif /* HAVE_EXPORT */ artist__remove = gtk_menu_item_new_with_label(_("Remove artist")); artist__separator2 = gtk_separator_menu_item_new(); artist__addrec = gtk_menu_item_new_with_label(_("Add new record to this artist...")); artist__separator3 = gtk_separator_menu_item_new(); artist__volume = gtk_menu_item_new_with_label(_("Calculate volume (recursive)")); artist__volume_menu = gtk_menu_new(); artist__volume_unmeasured = gtk_menu_item_new_with_label(_("Unmeasured tracks only")); artist__volume_all = gtk_menu_item_new_with_label(_("All tracks")); artist__tag = gtk_menu_item_new_with_label(_("Batch-update file metadata...")); artist__search = gtk_menu_item_new_with_label(_("Search...")); gtk_menu_shell_append(GTK_MENU_SHELL(artist_menu), artist__addlist); gtk_menu_shell_append(GTK_MENU_SHELL(artist_menu), artist__addlist_albummode); gtk_menu_shell_append(GTK_MENU_SHELL(artist_menu), artist__separator1); gtk_menu_shell_append(GTK_MENU_SHELL(artist_menu), artist__add); gtk_menu_shell_append(GTK_MENU_SHELL(artist_menu), artist__edit); #ifdef HAVE_EXPORT gtk_menu_shell_append(GTK_MENU_SHELL(artist_menu), artist__export); #endif /* HAVE_EXPORT */ gtk_menu_shell_append(GTK_MENU_SHELL(artist_menu), artist__remove); gtk_menu_shell_append(GTK_MENU_SHELL(artist_menu), artist__separator2); gtk_menu_shell_append(GTK_MENU_SHELL(artist_menu), artist__addrec); gtk_menu_shell_append(GTK_MENU_SHELL(artist_menu), artist__separator3); gtk_menu_shell_append(GTK_MENU_SHELL(artist_menu), artist__volume); gtk_menu_item_set_submenu(GTK_MENU_ITEM(artist__volume), artist__volume_menu); gtk_menu_shell_append(GTK_MENU_SHELL(artist__volume_menu), artist__volume_unmeasured); gtk_menu_shell_append(GTK_MENU_SHELL(artist__volume_menu), artist__volume_all); gtk_menu_shell_append(GTK_MENU_SHELL(artist_menu), artist__tag); gtk_menu_shell_append(GTK_MENU_SHELL(artist_menu), artist__search); g_signal_connect_swapped(G_OBJECT(artist__addlist), "activate", G_CALLBACK(artist__addlist_cb), NULL); g_signal_connect_swapped(G_OBJECT(artist__addlist_albummode), "activate", G_CALLBACK(artist__addlist_albummode_cb), NULL); g_signal_connect_swapped(G_OBJECT(artist__add), "activate", G_CALLBACK(artist__add_cb), NULL); g_signal_connect_swapped(G_OBJECT(artist__edit), "activate", G_CALLBACK(artist__edit_cb), NULL); #ifdef HAVE_EXPORT g_signal_connect_swapped(G_OBJECT(artist__export), "activate", G_CALLBACK(artist__export_cb), NULL); #endif /* HAVE_EXPORT */ g_signal_connect_swapped(G_OBJECT(artist__remove), "activate", G_CALLBACK(artist__remove_cb), NULL); g_signal_connect_swapped(G_OBJECT(artist__addrec), "activate", G_CALLBACK(record__add_cb), NULL); g_signal_connect_swapped(G_OBJECT(artist__volume_unmeasured), "activate", G_CALLBACK(artist__volume_unmeasured_cb), NULL); g_signal_connect_swapped(G_OBJECT(artist__volume_all), "activate", G_CALLBACK(artist__volume_all_cb), NULL); g_signal_connect_swapped(G_OBJECT(artist__tag), "activate", G_CALLBACK(artist__tag_cb), NULL); g_signal_connect_swapped(G_OBJECT(artist__search), "activate", G_CALLBACK(search_cb), NULL); gtk_widget_show(artist__addlist); gtk_widget_show(artist__addlist_albummode); gtk_widget_show(artist__separator1); gtk_widget_show(artist__add); gtk_widget_show(artist__edit); #ifdef HAVE_EXPORT gtk_widget_show(artist__export); #endif /* HAVE_EXPORT */ gtk_widget_show(artist__remove); gtk_widget_show(artist__separator2); gtk_widget_show(artist__addrec); gtk_widget_show(artist__separator3); gtk_widget_show(artist__volume); gtk_widget_show(artist__volume_unmeasured); gtk_widget_show(artist__volume_all); gtk_widget_show(artist__tag); gtk_widget_show(artist__search); /* create popup menu for record tree items */ record_menu = gtk_menu_new(); register_toplevel_window(record_menu, TOP_WIN_SKIN); record__addlist = gtk_menu_item_new_with_label(_("Add to playlist")); record__addlist_albummode = gtk_menu_item_new_with_label(_("Add to playlist (Album mode)")); record__separator1 = gtk_separator_menu_item_new(); record__add = gtk_menu_item_new_with_label(_("Add new record...")); record__edit = gtk_menu_item_new_with_label(_("Edit record...")); #ifdef HAVE_EXPORT record__export = gtk_menu_item_new_with_label(_("Export record...")); #endif /* HAVE_EXPORT */ record__remove = gtk_menu_item_new_with_label(_("Remove record")); record__separator2 = gtk_separator_menu_item_new(); record__addtrk = gtk_menu_item_new_with_label(_("Add new track to this record...")); #ifdef HAVE_CDDB record__cddb = gtk_menu_item_new_with_label(_("CDDB query for this record...")); record__cddb_submit = gtk_menu_item_new_with_label(_("Submit record to CDDB database...")); #endif /* HAVE_CDDB */ record__separator3 = gtk_separator_menu_item_new(); record__volume = gtk_menu_item_new_with_label(_("Calculate volume (recursive)")); record__volume_menu = gtk_menu_new(); record__volume_unmeasured = gtk_menu_item_new_with_label(_("Unmeasured tracks only")); record__volume_all = gtk_menu_item_new_with_label(_("All tracks")); record__tag = gtk_menu_item_new_with_label(_("Batch-update file metadata...")); record__search = gtk_menu_item_new_with_label(_("Search...")); gtk_menu_shell_append(GTK_MENU_SHELL(record_menu), record__addlist); gtk_menu_shell_append(GTK_MENU_SHELL(record_menu), record__addlist_albummode); gtk_menu_shell_append(GTK_MENU_SHELL(record_menu), record__separator1); gtk_menu_shell_append(GTK_MENU_SHELL(record_menu), record__add); gtk_menu_shell_append(GTK_MENU_SHELL(record_menu), record__edit); #ifdef HAVE_EXPORT gtk_menu_shell_append(GTK_MENU_SHELL(record_menu), record__export); #endif /* HAVE_EXPORT */ gtk_menu_shell_append(GTK_MENU_SHELL(record_menu), record__remove); gtk_menu_shell_append(GTK_MENU_SHELL(record_menu), record__separator2); gtk_menu_shell_append(GTK_MENU_SHELL(record_menu), record__addtrk); #ifdef HAVE_CDDB gtk_menu_shell_append(GTK_MENU_SHELL(record_menu), record__cddb); gtk_menu_shell_append(GTK_MENU_SHELL(record_menu), record__cddb_submit); #endif /* HAVE_CDDB */ gtk_menu_shell_append(GTK_MENU_SHELL(record_menu), record__separator3); gtk_menu_shell_append(GTK_MENU_SHELL(record_menu), record__volume); gtk_menu_item_set_submenu(GTK_MENU_ITEM(record__volume), record__volume_menu); gtk_menu_shell_append(GTK_MENU_SHELL(record__volume_menu), record__volume_unmeasured); gtk_menu_shell_append(GTK_MENU_SHELL(record__volume_menu), record__volume_all); gtk_menu_shell_append(GTK_MENU_SHELL(record_menu), record__tag); gtk_menu_shell_append(GTK_MENU_SHELL(record_menu), record__search); g_signal_connect_swapped(G_OBJECT(record__addlist), "activate", G_CALLBACK(record__addlist_cb), NULL); g_signal_connect_swapped(G_OBJECT(record__addlist_albummode), "activate", G_CALLBACK(record__addlist_albummode_cb), NULL); g_signal_connect_swapped(G_OBJECT(record__add), "activate", G_CALLBACK(record__add_cb), NULL); g_signal_connect_swapped(G_OBJECT(record__edit), "activate", G_CALLBACK(record__edit_cb), NULL); #ifdef HAVE_EXPORT g_signal_connect_swapped(G_OBJECT(record__export), "activate", G_CALLBACK(record__export_cb), NULL); #endif /* HAVE_EXPORT */ g_signal_connect_swapped(G_OBJECT(record__remove), "activate", G_CALLBACK(record__remove_cb), NULL); g_signal_connect_swapped(G_OBJECT(record__addtrk), "activate", G_CALLBACK(track__add_cb), NULL); #ifdef HAVE_CDDB g_signal_connect_swapped(G_OBJECT(record__cddb), "activate", G_CALLBACK(record__cddb_cb), NULL); g_signal_connect_swapped(G_OBJECT(record__cddb_submit), "activate", G_CALLBACK(record__cddb_submit_cb), NULL); #endif /* HAVE_CDDB */ g_signal_connect_swapped(G_OBJECT(record__volume_unmeasured), "activate", G_CALLBACK(record__volume_unmeasured_cb), NULL); g_signal_connect_swapped(G_OBJECT(record__volume_all), "activate", G_CALLBACK(record__volume_all_cb), NULL); g_signal_connect_swapped(G_OBJECT(record__tag), "activate", G_CALLBACK(record__tag_cb), NULL); g_signal_connect_swapped(G_OBJECT(record__search), "activate", G_CALLBACK(search_cb), NULL); gtk_widget_show(record__addlist); gtk_widget_show(record__addlist_albummode); gtk_widget_show(record__separator1); gtk_widget_show(record__add); gtk_widget_show(record__edit); #ifdef HAVE_EXPORT gtk_widget_show(record__export); #endif /* HAVE_EXPORT */ gtk_widget_show(record__remove); gtk_widget_show(record__separator2); gtk_widget_show(record__addtrk); #ifdef HAVE_CDDB gtk_widget_show(record__cddb); gtk_widget_show(record__cddb_submit); #endif /* HAVE_CDDB */ gtk_widget_show(record__separator3); gtk_widget_show(record__volume); gtk_widget_show(record__volume_unmeasured); gtk_widget_show(record__volume_all); gtk_widget_show(record__tag); gtk_widget_show(record__search); /* create popup menu for track tree items */ track_menu = gtk_menu_new(); register_toplevel_window(track_menu, TOP_WIN_SKIN); track__addlist = gtk_menu_item_new_with_label(_("Add to playlist")); track__separator1 = gtk_separator_menu_item_new(); track__add = gtk_menu_item_new_with_label(_("Add new track...")); track__edit = gtk_menu_item_new_with_label(_("Edit track...")); #ifdef HAVE_EXPORT track__export = gtk_menu_item_new_with_label(_("Export track...")); #endif /* HAVE_EXPORT */ track__remove = gtk_menu_item_new_with_label(_("Remove track")); track__separator2 = gtk_separator_menu_item_new(); track__fileinfo = gtk_menu_item_new_with_label(_("File info...")); track__separator3 = gtk_separator_menu_item_new(); track__volume = gtk_menu_item_new_with_label(_("Calculate volume")); track__volume_menu = gtk_menu_new(); track__volume_unmeasured = gtk_menu_item_new_with_label(_("Only if unmeasured")); track__volume_all = gtk_menu_item_new_with_label(_("In any case")); track__tag = gtk_menu_item_new_with_label(_("Update file metadata...")); track__search = gtk_menu_item_new_with_label(_("Search...")); gtk_menu_shell_append(GTK_MENU_SHELL(track_menu), track__addlist); gtk_menu_shell_append(GTK_MENU_SHELL(track_menu), track__separator1); gtk_menu_shell_append(GTK_MENU_SHELL(track_menu), track__add); gtk_menu_shell_append(GTK_MENU_SHELL(track_menu), track__edit); #ifdef HAVE_EXPORT gtk_menu_shell_append(GTK_MENU_SHELL(track_menu), track__export); #endif /* HAVE_EXPORT */ gtk_menu_shell_append(GTK_MENU_SHELL(track_menu), track__remove); gtk_menu_shell_append(GTK_MENU_SHELL(track_menu), track__separator2); gtk_menu_shell_append(GTK_MENU_SHELL(track_menu), track__fileinfo); gtk_menu_shell_append(GTK_MENU_SHELL(track_menu), track__separator3); gtk_menu_shell_append(GTK_MENU_SHELL(track_menu), track__volume); gtk_menu_item_set_submenu(GTK_MENU_ITEM(track__volume), track__volume_menu); gtk_menu_shell_append(GTK_MENU_SHELL(track__volume_menu), track__volume_unmeasured); gtk_menu_shell_append(GTK_MENU_SHELL(track__volume_menu), track__volume_all); gtk_menu_shell_append(GTK_MENU_SHELL(track_menu), track__tag); gtk_menu_shell_append(GTK_MENU_SHELL(track_menu), track__search); g_signal_connect_swapped(G_OBJECT(track__addlist), "activate", G_CALLBACK(track__addlist_cb), NULL); g_signal_connect_swapped(G_OBJECT(track__add), "activate", G_CALLBACK(track__add_cb), NULL); g_signal_connect_swapped(G_OBJECT(track__edit), "activate", G_CALLBACK(track__edit_cb), NULL); #ifdef HAVE_EXPORT g_signal_connect_swapped(G_OBJECT(track__export), "activate", G_CALLBACK(track__export_cb), NULL); #endif /* HAVE_EXPORT */ g_signal_connect_swapped(G_OBJECT(track__remove), "activate", G_CALLBACK(track__remove_cb), NULL); g_signal_connect_swapped(G_OBJECT(track__fileinfo), "activate", G_CALLBACK(track__fileinfo_cb), NULL); g_signal_connect_swapped(G_OBJECT(track__volume_unmeasured), "activate", G_CALLBACK(track__volume_unmeasured_cb), NULL); g_signal_connect_swapped(G_OBJECT(track__volume_all), "activate", G_CALLBACK(track__volume_all_cb), NULL); g_signal_connect_swapped(G_OBJECT(track__tag), "activate", G_CALLBACK(track__tag_cb), NULL); g_signal_connect_swapped(G_OBJECT(track__search), "activate", G_CALLBACK(search_cb), NULL); gtk_widget_show(track__addlist); gtk_widget_show(track__separator1); gtk_widget_show(track__add); gtk_widget_show(track__edit); #ifdef HAVE_EXPORT gtk_widget_show(track__export); #endif /* HAVE_EXPORT */ gtk_widget_show(track__remove); gtk_widget_show(track__separator2); gtk_widget_show(track__fileinfo); gtk_widget_show(track__separator3); gtk_widget_show(track__volume); gtk_widget_show(track__volume_unmeasured); gtk_widget_show(track__volume_all); gtk_widget_show(track__tag); gtk_widget_show(track__search); } void store_file_insert_progress_bar(GtkWidget * vbox) { ms_progress_bar_container = gtk_hbox_new(FALSE, 4); gtk_box_pack_start(GTK_BOX(vbox), ms_progress_bar_container, FALSE, FALSE, 1); if (ms_progress_bar_semaphore > 0) { ms_progress_bar_show(); } } void store_file_set_toolbar_sensitivity(GtkTreeIter * iter, GtkWidget * edit, GtkWidget * add, GtkWidget * remove) { GtkTreePath * p = gtk_tree_model_get_path(GTK_TREE_MODEL(music_store), iter); int depth = gtk_tree_path_get_depth(p); int val = !is_store_iter_readonly(iter); gtk_widget_set_sensitive(edit, val); gtk_widget_set_sensitive(add, val); gtk_widget_set_sensitive(remove, val || depth == 1); gtk_tree_path_free(p); } void store_file_toolbar__edit_cb(gpointer data) { GtkTreeModel * model; GtkTreeIter parent_iter; GtkTreePath * parent_path; gint level; if (gtk_tree_selection_get_selected(music_select, &model, &parent_iter)) { parent_path = gtk_tree_model_get_path(model, &parent_iter); level = gtk_tree_path_get_depth(parent_path); switch (level) { case 1: /* store */ store__edit_cb(NULL); break; case 2: /* artist */ artist__edit_cb(NULL); break; case 3: /* album */ record__edit_cb(NULL); break; case 4: /* track */ track__edit_cb(NULL); break; default: break; } } } void store_file_toolbar__add_cb(gpointer data) { GtkTreeModel * model; GtkTreeIter parent_iter; GtkTreePath * parent_path; gint level; if (gtk_tree_selection_get_selected(music_select, &model, &parent_iter)) { parent_path = gtk_tree_model_get_path(model, &parent_iter); level = gtk_tree_path_get_depth(parent_path); switch (level) { case 1: /* store */ store__add_cb(NULL); break; case 2: /* artist */ artist__add_cb(NULL); break; case 3: /* album */ record__add_cb(NULL); break; case 4: /* track */ track__add_cb(NULL); break; } } } void store_file_toolbar__remove_cb(gpointer data) { GtkTreeModel * model; GtkTreeIter parent_iter; GtkTreePath * parent_path; gint level; if (gtk_tree_selection_get_selected(music_select, &model, &parent_iter)) { parent_path = gtk_tree_model_get_path(model, &parent_iter); level = gtk_tree_path_get_depth(parent_path); switch (level) { case 1: /* store */ store__remove_cb(NULL); break; case 2: /* artist */ artist__remove_cb(NULL); break; case 3: /* album */ record__remove_cb(NULL); break; case 4: /* track */ track__remove_cb(NULL); break; } } } // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/store_podcast.h0000644000175000001440000000460010701710463014722 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: store_podcast.h 820 2007-09-02 10:41:41Z peterszilagyi $ */ #ifndef _STORE_PODCAST_H #define _STORE_PODCAST_H #include #ifdef HAVE_PODCAST #include #include "podcast.h" int store_podcast_iter_is_track(GtkTreeIter * iter); void store_podcast_iter_addlist_defmode(GtkTreeIter * ms_iter, GtkTreeIter * pl_iter, int new_tab); void store_podcast_selection_changed(GtkTreeIter * iter, GtkTextBuffer * buffer, GtkLabel * statusbar); gboolean store_podcast_event_cb(GdkEvent * event, GtkTreeIter * iter, GtkTreePath * path); void store_podcast_load_icons(void); void store_podcast_create_popup_menu(void); void store_podcast_set_toolbar_sensitivity(GtkTreeIter * iter, GtkWidget * edit, GtkWidget * add, GtkWidget * remove); void store_podcast_toolbar__edit_cb(gpointer data); void store_podcast_toolbar__add_cb(gpointer data); void store_podcast_toolbar__remove_cb(gpointer data); void create_podcast_node(void); void store_podcast_updater_start(void); typedef struct { podcast_t * podcast; int ncurrent; int ndownloads; int percent; } podcast_download_t; podcast_download_t * podcast_download_new(podcast_t * podcast); void store_podcast_update_podcast(podcast_download_t * pd); void store_podcast_update_podcast_download(podcast_download_t * pd); void store_podcast_add_item(podcast_t * podcast, podcast_item_t * item); void store_podcast_remove_item(podcast_t * podcast, podcast_item_t * item); void store_podcast_save(void); void store_podcast_load(void); #endif /* HAVE_PODCAST */ #endif /* _STORE_PODCAST_H */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/store_podcast.c0000644000175000001440000017103711002132477014724 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: store_podcast.c 1021 2008-04-16 10:16:36Z tszilagyi $ */ #include #ifdef HAVE_PODCAST #include #include #include #include #include #include #include #include #ifdef _WIN32 #include #else #include #endif /* _WIN32 */ #include "common.h" #include "i18n.h" #include "utils.h" #include "utils_gui.h" #include "options.h" #include "file_info.h" #include "export.h" #include "playlist.h" #include "music_browser.h" #include "podcast.h" #include "store_podcast.h" extern options_t options; extern char pl_color_inactive[14]; extern GtkWidget * browser_window; extern GtkTreeStore * music_store; extern GtkTreeSelection * music_select; extern GdkPixbuf * icon_track; GdkPixbuf * icon_feed; GdkPixbuf * icon_podcasts; GtkWidget * podcast_track_menu; GtkWidget * podcast_track__addlist; #ifdef HAVE_EXPORT GtkWidget * podcast_track__export; #endif /* HAVE_EXPORT */ GtkWidget * podcast_track__fileinfo; GtkWidget * podcast_feed_menu; GtkWidget * podcast_feed__addlist; GtkWidget * podcast_feed__addlist_albummode; GtkWidget * podcast_feed__addlist_new; GtkWidget * podcast_feed__addlist_albummode_new; GtkWidget * podcast_feed__subscribe; GtkWidget * podcast_feed__edit; GtkWidget * podcast_feed__update; GtkWidget * podcast_feed__abort; GtkWidget * podcast_feed__remove; #ifdef HAVE_EXPORT GtkWidget * podcast_feed__export; GtkWidget * podcast_feed__export_new; #endif /* HAVE_EXPORT */ GtkWidget * podcast_store_menu; GtkWidget * podcast_store__addlist; GtkWidget * podcast_store__addlist_albummode; GtkWidget * podcast_store__addlist_new; GtkWidget * podcast_store__addlist_albummode_new; GtkWidget * podcast_store__subscribe; GtkWidget * podcast_store__update; GtkWidget * podcast_store__reorder; #ifdef HAVE_EXPORT GtkWidget * podcast_store__export; GtkWidget * podcast_store__export_new; #endif /* HAVE_EXPORT */ GtkWidget * podcast_store__update_enabled; void podcast_store__addlist_defmode(gpointer data); void podcast_store__update_cb(gpointer data); void podcast_feed__addlist_defmode(gpointer data); void podcast_feed__subscribe_cb(gpointer data); void podcast_feed__edit_cb(gpointer data); void podcast_feed__update_cb(gpointer data); void podcast_feed__remove_cb(gpointer data); void podcast_track__addlist_cb(gpointer data); void podcast_track__fileinfo_cb(gpointer data); #ifdef HAVE_EXPORT void podcast_store__export_cb(gpointer data); void podcast_feed__export_cb(gpointer data); void podcast_track__export_cb(gpointer data); #endif /* HAVE_EXPORT */ struct keybinds podcast_store_keybinds[] = { {podcast_store__addlist_defmode, GDK_a, GDK_A, 0}, {podcast_store__update_cb, GDK_u, GDK_U, 0}, #ifdef HAVE_EXPORT {podcast_store__export_cb, GDK_x, GDK_X, 0}, #endif /* HAVE_EXPORT */ {podcast_feed__subscribe_cb, GDK_n, GDK_N, GDK_CONTROL_MASK}, {NULL, 0, 0} }; struct keybinds podcast_feed_keybinds[] = { {podcast_feed__addlist_defmode, GDK_a, GDK_A, 0}, {podcast_feed__subscribe_cb, GDK_n, GDK_N, 0}, {podcast_feed__edit_cb, GDK_e, GDK_E, 0}, {podcast_feed__update_cb, GDK_u, GDK_U, 0}, {podcast_feed__remove_cb, GDK_Delete, GDK_KP_Delete, 0}, #ifdef HAVE_EXPORT {podcast_feed__export_cb, GDK_x, GDK_X, 0}, #endif /* HAVE_EXPORT */ {NULL, 0, 0} }; struct keybinds podcast_track_keybinds[] = { {podcast_track__addlist_cb, GDK_a, GDK_A, 0}, {podcast_track__fileinfo_cb, GDK_i, GDK_I, 0}, #ifdef HAVE_EXPORT {podcast_track__export_cb, GDK_x, GDK_X, 0}, #endif /* HAVE_EXPORT */ {NULL, 0, 0} }; gboolean store_podcast_remove_podcast_item(GtkTreeIter * iter) { podcast_item_t * item; gtk_tree_model_get(GTK_TREE_MODEL(music_store), iter, MS_COL_DATA, &item, -1); podcast_item_free(item); return gtk_tree_store_remove(music_store, iter); } gboolean store_podcast_remove_podcast(GtkTreeIter * iter) { podcast_t * podcast; GtkTreeIter track_iter; int i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &track_iter, iter, i++)) { store_podcast_remove_podcast_item(&track_iter); } gtk_tree_model_get(GTK_TREE_MODEL(music_store), iter, MS_COL_DATA, &podcast, -1); podcast_free(podcast); return gtk_tree_store_remove(music_store, iter); } int store_podcast_get_store_iter(GtkTreeIter * store_iter) { store_t * data; GtkTreeIter iter; int i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &iter, NULL, i++)) { gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter, MS_COL_DATA, &data, -1); if (data->type == STORE_TYPE_PODCAST) { *store_iter = iter; return 0; } } printf("WARNING: store_podcast_get_store_iter could not find store iter\n"); return -1; } int store_podcast_get_pod_iter(GtkTreeIter * pod_iter, podcast_t * podcast) { podcast_t * data; GtkTreeIter store_iter; GtkTreeIter iter; int i = 0; if (store_podcast_get_store_iter(&store_iter) != 0) { return 0; } while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &iter, &store_iter, i++)) { gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter, MS_COL_DATA, &data, -1); if (podcast == data) { *pod_iter = iter; return 0; } } printf("WARNING: store_podcast_get_pod_iter could not find podcast iter\n"); return -1; } /*************************************************/ void podcast_browse_button_clicked(GtkButton * button, gpointer data) { file_chooser_with_entry(_("Please select the download directory for this podcast."), browser_window, GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, FILE_CHOOSER_FILTER_NONE, (GtkWidget *)data, options.podcastdir); } void check_button_toggle_sensitivity(GtkToggleButton * togglebutton, gpointer data) { if (gtk_toggle_button_get_active(togglebutton)) { gtk_widget_set_sensitive((GtkWidget *)data, TRUE); } else { gtk_widget_set_sensitive((GtkWidget *)data, FALSE); } } void insert_check_label_spin(GtkWidget * table, GtkWidget ** check, char * ltext, GtkWidget ** spin, double spinval, double min, double max, int y1, int y2, int active) { *check = gtk_check_button_new_with_label(ltext); gtk_widget_set_name(*check, "check_on_window"); gtk_table_attach(GTK_TABLE(table), *check, 0, 1, y1, y2, GTK_FILL, GTK_FILL, 5, 5); *spin = gtk_spin_button_new_with_range(min, max, 1); gtk_spin_button_set_value(GTK_SPIN_BUTTON(*spin), spinval); gtk_table_attach(GTK_TABLE(table), *spin, 1, 2, y1, y2, GTK_EXPAND | GTK_FILL, GTK_FILL, 2, 5); g_signal_connect(G_OBJECT(*check), "toggled", G_CALLBACK(check_button_toggle_sensitivity), *spin); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(*check), active); gtk_widget_set_sensitive(*spin, active); } /* create == 1 : add new podcast; else edit existing podcast */ int podcast_dialog(podcast_t ** podcast, int create) { GtkWidget * dialog; GtkWidget * table; GtkWidget * url_entry; GtkWidget * dir_entry; GtkWidget * check_check; GtkWidget * check_spin; GtkWidget * frame; GtkWidget * count_check; GtkWidget * date_check; GtkWidget * size_check; GtkWidget * count_spin; GtkWidget * date_spin; GtkWidget * size_spin; dialog = gtk_dialog_new_with_buttons(create ? _("Subscribe to new feed") : _("Edit feed settings"), GTK_WINDOW(browser_window), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL); gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER_ON_PARENT); gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT); table = gtk_table_new(3, 2, FALSE); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), table, FALSE, TRUE, 2); insert_label_entry(table, _("Podcast URL:"), &url_entry, create ? NULL : (*podcast)->url, 0, 1, create); if (create) { insert_label_entry_browse(table, _("Download directory:"), &dir_entry, options.podcastdir, 1, 2, podcast_browse_button_clicked); } else { insert_label_entry(table, _("Download directory:"), &dir_entry, (*podcast)->dir, 1, 2, FALSE); } if (options.podcasts_autocheck || create) { insert_check_label_spin(table, &check_check, _("Auto-check interval [hour]:"), &check_spin, create ? 1.0 : (*podcast)->check_interval / 3600.0, 0.25, 168.0, 3, 4, create || (*podcast)->flags & PODCAST_AUTO_CHECK); gtk_spin_button_set_digits(GTK_SPIN_BUTTON(check_spin), 2); gtk_spin_button_set_increments(GTK_SPIN_BUTTON(check_spin), 0.25, 1.0); } else { GtkWidget * label = gtk_label_new(_("Automatic update has been disabled for all feeds\n" "in the Podcasts store popup menu.")); GtkWidget * icon = gtk_image_new_from_stock(GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_BUTTON); GtkWidget * hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), icon, FALSE, FALSE, 5); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5); gtk_table_attach(GTK_TABLE(table), hbox, 0, 2, 3, 4, GTK_FILL, GTK_FILL, 5, 5); } frame = gtk_frame_new(_("Limits")); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), frame, FALSE, TRUE, 5); table = gtk_table_new(3, 2, FALSE); gtk_container_add(GTK_CONTAINER(frame), table); insert_check_label_spin(table, &count_check, _("Maximum number of items:"), &count_spin, create ? 10 : (*podcast)->count_limit, 0, 100, 0, 1, create || (*podcast)->flags & PODCAST_COUNT_LIMIT); insert_check_label_spin(table, &date_check, _("Remove older items [day]:"), &date_spin, create ? 14 : (*podcast)->date_limit / 86400, 0, 100, 1, 2, create ? FALSE : (*podcast)->flags & PODCAST_DATE_LIMIT); insert_check_label_spin(table, &size_check, _("Maximum space to use [MB]:"), &size_spin, create ? 100 : (*podcast)->size_limit / (1024 * 1024), 0, 1024, 2, 3, create || (*podcast)->flags & PODCAST_SIZE_LIMIT); gtk_widget_grab_focus(url_entry); gtk_widget_show_all(dialog); display: if (aqualung_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { if (create) { const char * pdir = g_filename_from_utf8(gtk_entry_get_text(GTK_ENTRY(dir_entry)), -1, NULL, NULL, NULL); char dir[MAXLEN]; char url[MAXLEN]; strncpy(url, gtk_entry_get_text(GTK_ENTRY(url_entry)), MAXLEN-1); if (url[0] == '\0') { gtk_widget_grab_focus(url_entry); goto display; } dir[0] = '\0'; if (pdir == NULL || pdir[0] == '\0') { gtk_widget_grab_focus(dir_entry); goto display; } if ((*podcast = podcast_new()) == NULL) { return 0; } normalize_filename(pdir, dir); (*podcast)->dir = strdup(dir); (*podcast)->url = strdup(url); strncpy(options.podcastdir, dir, MAXLEN-1); } if (options.podcasts_autocheck || create) { (*podcast)->check_interval = gtk_spin_button_get_value(GTK_SPIN_BUTTON(check_spin)) * 3600; set_option_bit_from_toggle(check_check, &(*podcast)->flags, PODCAST_AUTO_CHECK); } set_option_bit_from_toggle(count_check, &(*podcast)->flags, PODCAST_COUNT_LIMIT); set_option_bit_from_toggle(date_check, &(*podcast)->flags, PODCAST_DATE_LIMIT); set_option_bit_from_toggle(size_check, &(*podcast)->flags, PODCAST_SIZE_LIMIT); (*podcast)->count_limit = gtk_spin_button_get_value(GTK_SPIN_BUTTON(count_spin)); (*podcast)->date_limit = gtk_spin_button_get_value(GTK_SPIN_BUTTON(date_spin)) * 86400; (*podcast)->size_limit = gtk_spin_button_get_value(GTK_SPIN_BUTTON(size_spin)) * 1024 * 1024; gtk_widget_destroy(dialog); return 1; } else { gtk_widget_destroy(dialog); return 0; } } void podcast_track_mark_read(GtkTreeIter * iter, podcast_item_t * item) { item->new = 0; gtk_tree_store_set(music_store, iter, MS_COL_FONT, PANGO_WEIGHT_NORMAL, -1); } /* returns the duration of the track */ float podcast_track_addlist_iter(GtkTreeIter iter_track, playlist_t * pl, GtkTreeIter * parent, GtkTreeIter * dest, int new) { GtkTreeIter dest_parent; GtkTreeIter pod_iter; GtkTreeIter list_iter; podcast_t * podcast; podcast_item_t * item; char list_str[MAXLEN]; char duration_str[MAXLEN]; playlist_data_t * pldata = NULL; gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter_track, MS_COL_DATA, &item, -1); if (new && !item->new) { return 0.0f; } gtk_tree_model_iter_parent(GTK_TREE_MODEL(music_store), &pod_iter, &iter_track); gtk_tree_model_get(GTK_TREE_MODEL(music_store), &pod_iter, MS_COL_DATA, &podcast, -1); if (parent != NULL || (dest != NULL && gtk_tree_model_iter_parent(GTK_TREE_MODEL(pl->store), &dest_parent, dest))) { GtkTreeIter * piter = (parent != NULL) ? parent : &dest_parent; playlist_data_t * pdata; gtk_tree_model_get(GTK_TREE_MODEL(pl->store), piter, PL_COL_DATA, &pdata, -1); if (pdata->artist && pdata->album && podcast->author && podcast->title && !strcmp(pdata->artist, podcast->author) && !strcmp(pdata->album, podcast->title)) { strcpy(list_str, item->title); } else { make_title_string(list_str, options.title_format, podcast->author, podcast->title, item->title); } } else { make_title_string(list_str, options.title_format, podcast->author, podcast->title, item->title); } time2time(item->duration, duration_str); if ((pldata = playlist_data_new()) == NULL) { return 0; } if (podcast->author) { pldata->artist = strndup(podcast->author, MAXLEN-1); } pldata->album = strdup(podcast->title); pldata->title = strdup(item->title); pldata->file = strdup(item->file); pldata->size = item->size; pldata->duration = item->duration; pldata->flags = PL_FLAG_COVER; /* either parent or dest should be set, but not both */ gtk_tree_store_insert_before(pl->store, &list_iter, parent, dest); gtk_tree_store_set(pl->store, &list_iter, PL_COL_NAME, list_str, PL_COL_VADJ, "", PL_COL_DURA, duration_str, PL_COL_COLO, pl_color_inactive, PL_COL_FONT, PANGO_WEIGHT_NORMAL, PL_COL_DATA, pldata, -1); podcast_track_mark_read(&iter_track, item); return item->duration; } void podcast_feed_addlist_iter(GtkTreeIter iter_record, playlist_t * pl, GtkTreeIter * dest, int album_mode, int new) { GtkTreeIter iter_track; GtkTreeIter list_iter; GtkTreeIter * plist_iter; int i; float record_duration = 0.0f; playlist_data_t * pldata = NULL; if (gtk_tree_model_iter_n_children(GTK_TREE_MODEL(music_store), &iter_record) == 0) { return; } if (album_mode && new) { int has_new = 0; i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &iter_track, &iter_record, i++)) { podcast_item_t * item; gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter_track, MS_COL_DATA, &item, -1); if (item->new) { has_new = 1; break; } } if (!has_new) { return; } } if (album_mode) { char list_str[MAXLEN]; podcast_t * podcast; if ((pldata = playlist_data_new()) == NULL) { return; } gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter_record, MS_COL_DATA, &podcast, -1); snprintf(list_str, MAXLEN-1, "%s: %s", podcast->author ? podcast->author : _("Podcasts"), podcast->title); pldata->artist = strndup(podcast->author ? podcast->author : _("Podcasts"), MAXLEN-1); pldata->album = strdup(podcast->title); gtk_tree_store_insert_before(pl->store, &list_iter, NULL, dest); gtk_tree_store_set(pl->store, &list_iter, PL_COL_NAME, list_str, PL_COL_VADJ, "", PL_COL_DURA, "00:00", PL_COL_COLO, pl_color_inactive, PL_COL_FONT, PANGO_WEIGHT_NORMAL, PL_COL_DATA, pldata, -1); plist_iter = &list_iter; dest = NULL; } else { plist_iter = NULL; } i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &iter_track, &iter_record, i++)) { record_duration += podcast_track_addlist_iter(iter_track, pl, plist_iter, dest, new); } if (album_mode) { char duration_str[MAXLEN]; pldata->duration = record_duration; time2time(record_duration, duration_str); gtk_tree_store_set(pl->store, &list_iter, PL_COL_DURA, duration_str, -1); } } void podcast_track__addlist_cb(gpointer data) { GtkTreeIter iter_track; playlist_t * pl = playlist_get_current(); if (gtk_tree_selection_get_selected(music_select, NULL, &iter_track)) { podcast_track_addlist_iter(iter_track, pl, NULL, (GtkTreeIter *)data, 0); if (pl == playlist_get_current()) { playlist_content_changed(pl); } store_podcast_save(); } } void podcast_track__fileinfo_cb(gpointer data) { GtkTreeIter iter_track; GtkTreeIter pod_iter; GtkTreeModel * model; char list_str[MAXLEN]; if (gtk_tree_selection_get_selected(music_select, &model, &iter_track)) { podcast_item_t * item; podcast_t * podcast; gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter_track, MS_COL_DATA, &item, -1); gtk_tree_model_iter_parent(GTK_TREE_MODEL(music_store), &pod_iter, &iter_track); gtk_tree_model_get(GTK_TREE_MODEL(music_store), &pod_iter, MS_COL_DATA, &podcast, -1); make_title_string(list_str, options.title_format, podcast->author, podcast->title, item->title); show_file_info(list_str, item->file, 0, model, iter_track, TRUE); } } void podcast_feed__addlist_with_mode(int mode, int new, gpointer data) { GtkTreeIter iter_record; playlist_t * pl = playlist_get_current(); if (gtk_tree_selection_get_selected(music_select, NULL, &iter_record)) { podcast_feed_addlist_iter(iter_record, pl, (GtkTreeIter *)data, mode, new); if (pl == playlist_get_current()) { playlist_content_changed(pl); } store_podcast_save(); } } void podcast_feed__addlist_defmode(gpointer data) { podcast_feed__addlist_with_mode(options.playlist_is_tree, 0, data); } void podcast_feed__addlist_albummode_cb(gpointer data) { podcast_feed__addlist_with_mode(1, 0, data); } void podcast_feed__addlist_cb(gpointer data) { podcast_feed__addlist_with_mode(0, 0, data); } void podcast_feed__addlist_albummode_new_cb(gpointer data) { podcast_feed__addlist_with_mode(1, 1, data); } void podcast_feed__addlist_new_cb(gpointer data) { podcast_feed__addlist_with_mode(0, 1, data); } void podcast_store_addlist_iter(GtkTreeIter iter_store, playlist_t * pl, GtkTreeIter * dest, int album_mode, int new) { GtkTreeIter pod_iter; int i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &pod_iter, &iter_store, i++)) { podcast_feed_addlist_iter(pod_iter, pl, dest, album_mode, new); } } void podcast_store__addlist_with_mode(int mode, int new, gpointer data) { GtkTreeIter iter_store; playlist_t * pl = playlist_get_current(); if (gtk_tree_selection_get_selected(music_select, NULL, &iter_store)) { podcast_store_addlist_iter(iter_store, pl, (GtkTreeIter *)data, mode, new); if (pl == playlist_get_current()) { playlist_content_changed(pl); } store_podcast_save(); } } void podcast_store__addlist_defmode(gpointer data) { podcast_store__addlist_with_mode(options.playlist_is_tree, 0, data); } void podcast_store__addlist_albummode_cb(gpointer data) { podcast_store__addlist_with_mode(1, 0, data); } void podcast_store__addlist_cb(gpointer data) { podcast_store__addlist_with_mode(0, 0, data); } void podcast_store__addlist_albummode_new_cb(gpointer data) { podcast_store__addlist_with_mode(1, 1, data); } void podcast_store__addlist_new_cb(gpointer data) { podcast_store__addlist_with_mode(0, 1, data); } void podcast_feed__subscribe_cb(gpointer data) { podcast_t * podcast; if (podcast_dialog(&podcast, 1/*create*/)) { GtkTreeIter store_iter; GtkTreeIter pod_iter; store_podcast_get_store_iter(&store_iter); gtk_tree_store_append(music_store, &pod_iter, &store_iter); gtk_tree_store_set(music_store, &pod_iter, MS_COL_NAME, _("Updating..."), MS_COL_DATA, podcast, -1); if (options.enable_ms_tree_icons) { gtk_tree_store_set(music_store, &pod_iter, MS_COL_ICON, icon_feed, -1); } store_podcast_save(); podcast_update(podcast); } } void podcast_feed__edit_cb(gpointer data) { GtkTreeIter iter; if (gtk_tree_selection_get_selected(music_select, NULL, &iter)) { podcast_t * podcast; gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter, MS_COL_DATA, &podcast, -1); if (podcast->state != PODCAST_STATE_IDLE) { return; } podcast->state = PODCAST_STATE_UPDATE; if (podcast_dialog(&podcast, 0/*edit*/)) { store_podcast_save(); } podcast->state = PODCAST_STATE_IDLE; } } void podcast_feed__update_cb(gpointer data) { GtkTreeIter iter; if (gtk_tree_selection_get_selected(music_select, NULL, &iter)) { podcast_t * podcast; gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter, MS_COL_DATA, &podcast, -1); if (podcast->state != PODCAST_STATE_IDLE) { return; } gtk_tree_store_set(music_store, &iter, MS_COL_NAME, _("Updating..."), -1); podcast_update(podcast); } } void podcast_feed__abort_cb(gpointer data) { GtkTreeIter iter; if (gtk_tree_selection_get_selected(music_select, NULL, &iter)) { podcast_t * podcast; gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter, MS_COL_DATA, &podcast, -1); if (podcast->state == PODCAST_STATE_UPDATE) { podcast->state = PODCAST_STATE_ABORTED; } } } void podcast_feed__remove_check_cb(GtkWidget * widget, gpointer data) { set_option_from_toggle(widget, (int *)data); } void podcast_feed__remove_cb(gpointer data) { GtkTreeIter iter; if (gtk_tree_selection_get_selected(music_select, NULL, &iter)) { GtkWidget * check; int unlink_files = 1; podcast_t * podcast; char * title; gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter, MS_COL_DATA, &podcast, -1); if (podcast->state != PODCAST_STATE_IDLE) { return; } gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter, MS_COL_NAME, &title, -1); check = gtk_check_button_new_with_label(_("Delete downloaded items from the filesystem")); gtk_widget_set_name(check, "check_on_window"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), unlink_files); g_signal_connect(G_OBJECT(check), "toggled", G_CALLBACK(podcast_feed__remove_check_cb), &unlink_files); if (message_dialog(_("Remove feed"), browser_window, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, check, _("Really remove '%s' from the Music Store?"), title) == GTK_RESPONSE_YES) { if (unlink_files) { GSList * node; for (node = podcast->items; node; node = node->next) { unlink(((podcast_item_t *)node->data)->file); } } store_podcast_remove_podcast(&iter); store_podcast_save(); } g_free(title); } } gboolean podcast_delayed_update_cb(gpointer data) { podcast_update((podcast_t *)data); return FALSE; } /* data != NULL indicates automatic update */ void podcast_store__update_cb(gpointer data) { podcast_t * podcast; GtkTreeIter store_iter; GtkTreeIter iter; GTimeVal tval; int i = 0; if (store_podcast_get_store_iter(&store_iter) != 0) { return; } if (data != NULL) { g_get_current_time(&tval); } for (i = 0; gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &iter, &store_iter, i); ++i) { gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter, MS_COL_DATA, &podcast, -1); if (podcast->state != PODCAST_STATE_IDLE) { continue; } if (data != NULL) { if (!(podcast->flags & PODCAST_AUTO_CHECK)) { /* auto check not enabled */ continue; } if (tval.tv_sec - podcast->last_checked < podcast->check_interval) { /* too young to be updated */ continue; } } podcast->state = PODCAST_STATE_PENDING; gtk_tree_store_set(music_store, &iter, MS_COL_NAME, _("Updating..."), -1); aqualung_timeout_add(1000 * i, podcast_delayed_update_cb, podcast); } } void podcast_store__reorder_cb(gpointer data) { GtkWidget * dialog; GtkWidget * label; GtkWidget * list; GtkWidget * viewport; GtkListStore * store; GtkCellRenderer * renderer; GtkTreeViewColumn * column; GtkTreeIter store_iter; GtkTreeIter pod_iter; GtkTreeIter list_iter; int i, res; dialog = gtk_dialog_new_with_buttons(_("Reorder feeds"), GTK_WINDOW(browser_window), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL); gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER_ON_PARENT); gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT); store = gtk_list_store_new(2, G_TYPE_STRING, /* title */ G_TYPE_POINTER); /* GtkTreeIter */ label = gtk_label_new(_("Drag and drop entries in the list\n" "to set the feed order in the Music Store.")); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), label, FALSE, FALSE, 5); list = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store)); renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes("", renderer, "text", 0, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(list), column); gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(list), FALSE); gtk_tree_view_set_reorderable(GTK_TREE_VIEW(list), TRUE); viewport = gtk_viewport_new(NULL, NULL); gtk_container_add(GTK_CONTAINER(viewport), list); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), viewport, TRUE, TRUE, 5); i = 0; store_podcast_get_store_iter(&store_iter); while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &pod_iter, &store_iter, i++)) { char title[MAXLEN]; podcast_t * podcast; GtkTreePath * path; gtk_tree_model_get(GTK_TREE_MODEL(music_store), &pod_iter, MS_COL_DATA, &podcast, -1); podcast_get_display_name(podcast, title); path = gtk_tree_model_get_path(GTK_TREE_MODEL(music_store), &pod_iter); gtk_list_store_append(store, &list_iter); gtk_list_store_set(store, &list_iter, 0, title, 1, gtk_tree_iter_copy(&pod_iter), -1); } gtk_widget_show_all(dialog); res = aqualung_dialog_run(GTK_DIALOG(dialog)); i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(store), &list_iter, NULL, i++)) { GtkTreeIter * iter; gtk_tree_model_get(GTK_TREE_MODEL(store), &list_iter, 1, &iter, -1); if (res == GTK_RESPONSE_ACCEPT) { char sort[16]; snprintf(sort, 15, "%03d", i); gtk_tree_store_set(music_store, iter, MS_COL_SORT, sort, -1); } gtk_tree_iter_free(iter); } if (res == GTK_RESPONSE_ACCEPT) { store_podcast_save(); } gtk_widget_destroy(dialog); } void podcast_store__update_enabled_cb(gpointer data) { if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(podcast_store__update_enabled))) { options.podcasts_autocheck = 1; } else { options.podcasts_autocheck = 0; } } void podcast_tree_mark_read(GtkTreeIter * iter, int depth) { if (depth == 3) { podcast_item_t * item; gtk_tree_model_get(GTK_TREE_MODEL(music_store), iter, MS_COL_DATA, &item, -1); podcast_track_mark_read(iter, item); } else { GtkTreeIter iter_child; int i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &iter_child, iter, i++)) { podcast_tree_mark_read(&iter_child, depth + 1); } } } #ifdef HAVE_EXPORT void podcast_track_export(GtkTreeIter * iter_track, export_t * export, char * author, char * feed, int new_only) { podcast_item_t * item; podcast_t * podcast; char artist[MAXLEN]; char album[MAXLEN]; char * title; gtk_tree_model_get(GTK_TREE_MODEL(music_store), iter_track, MS_COL_DATA, &item, -1); if (new_only && !item->new) { return; } gtk_tree_model_get(GTK_TREE_MODEL(music_store), iter_track, MS_COL_NAME, &title, -1); if (author == NULL || feed == NULL) { GtkTreeIter iter_podcast; gtk_tree_model_iter_parent(GTK_TREE_MODEL(music_store), &iter_podcast, iter_track); gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter_podcast, MS_COL_DATA, &podcast, -1); } strncpy(artist, (author == NULL) ? podcast->author : author, MAXLEN-1); strncpy(album, (feed == NULL) ? podcast->title : feed, MAXLEN-1); export_append_item(export, item->file, artist, album, title, 0, 0); g_free(title); } void podcast_feed_export(GtkTreeIter * iter_podcast, export_t * export, int new_only) { GtkTreeIter iter_track; podcast_t * podcast; int i; gtk_tree_model_get(GTK_TREE_MODEL(music_store), iter_podcast, MS_COL_DATA, &podcast, -1); i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &iter_track, iter_podcast, i++)) { podcast_track_export(&iter_track, export, podcast->author, podcast->title, new_only); } } void podcast_track__export_cb(gpointer user_data) { GtkTreeIter iter_track; export_t * export; if (gtk_tree_selection_get_selected(music_select, NULL, &iter_track)) { if ((export = export_new()) == NULL) { return; } podcast_track_export(&iter_track, export, NULL, NULL, 0); if (export_start(export)) { podcast_tree_mark_read(&iter_track, 3); store_podcast_save(); } } } void podcast_feed__export_cb(gpointer user_data) { GtkTreeIter iter_podcast; export_t * export; if (gtk_tree_selection_get_selected(music_select, NULL, &iter_podcast)) { if ((export = export_new()) == NULL) { return; } podcast_feed_export(&iter_podcast, export, (user_data == (gpointer)1) ? 1 : 0); if (export_start(export)) { podcast_tree_mark_read(&iter_podcast, 2); store_podcast_save(); } } } void podcast_store__export_cb(gpointer user_data) { GtkTreeIter iter_store; GtkTreeIter iter_podcast; export_t * export; int i; if (gtk_tree_selection_get_selected(music_select, NULL, &iter_store)) { if ((export = export_new()) == NULL) { return; } i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &iter_podcast, &iter_store, i++)) { podcast_feed_export(&iter_podcast, export, (user_data == (gpointer)1) ? 1 : 0); } if (export_start(export)) { podcast_tree_mark_read(&iter_store, 1); store_podcast_save(); } } } #endif /* HAVE_EXPORT */ /*************************************************/ typedef struct { podcast_t * podcast; podcast_item_t * item; } podcast_transfer_t; podcast_transfer_t * podcast_transfer_new(podcast_t * podcast, podcast_item_t * item) { podcast_transfer_t * pt; if ((pt = (podcast_transfer_t *)malloc(sizeof(podcast_transfer_t))) == NULL) { fprintf(stderr, "podcast_transfer_new: malloc error\n"); return NULL; } pt->podcast = podcast; pt->item = item; return pt; } podcast_download_t * podcast_download_new(podcast_t * podcast) { podcast_download_t * pd; if ((pd = (podcast_download_t *)calloc(1, sizeof(podcast_download_t))) == NULL) { fprintf(stderr, "podcast_download_new: calloc error\n"); return NULL; } pd->podcast = podcast; return pd; } void podcast_iter_set_display_name(podcast_t * podcast, GtkTreeIter * pod_iter) { char name_str[MAXLEN]; podcast_get_display_name(podcast, name_str); gtk_tree_store_set(music_store, pod_iter, MS_COL_NAME, name_str, -1); } gboolean store_podcast_update_podcast_cb(gpointer data) { podcast_download_t * pd = (podcast_download_t *)data; GtkTreeIter pod_iter; if (store_podcast_get_pod_iter(&pod_iter, pd->podcast) != 0) { return FALSE; } podcast_iter_set_display_name(pd->podcast, &pod_iter); store_podcast_save(); pd->podcast->state = PODCAST_STATE_IDLE; free(pd); return FALSE; } gboolean store_podcast_update_podcast_download_cb(gpointer data) { podcast_download_t * pd = (podcast_download_t *)data; GtkTreeIter pod_iter; char name_str[MAXLEN]; if (store_podcast_get_pod_iter(&pod_iter, pd->podcast) != 0) { return FALSE; } snprintf(name_str, MAXLEN-1, _("Downloading %d/%d (%d%%) ..."), pd->ncurrent, pd->ndownloads, pd->percent); gtk_tree_store_set(music_store, &pod_iter, MS_COL_NAME, name_str, -1); return FALSE; } gboolean store_podcast_add_item_cb(gpointer data) { podcast_transfer_t * pt = (podcast_transfer_t *)data; GtkTreeIter pod_iter; GtkTreeIter iter; char sort[16]; if (store_podcast_get_pod_iter(&pod_iter, pt->podcast) != 0) { return FALSE; } snprintf(sort, 15, "%014lld", 10000000000LL - pt->item->date); gtk_tree_store_append(music_store, &iter, &pod_iter); gtk_tree_store_set(music_store, &iter, MS_COL_NAME, pt->item->title, MS_COL_SORT, sort, MS_COL_FONT, PANGO_WEIGHT_BOLD, MS_COL_DATA, pt->item, -1); if (options.enable_ms_tree_icons) { gtk_tree_store_set(music_store, &iter, MS_COL_ICON, icon_track, -1); } free(pt); store_podcast_save(); return FALSE; } gboolean store_podcast_remove_item_cb(gpointer data) { podcast_transfer_t * pt = (podcast_transfer_t *)data; podcast_item_t * item; GtkTreeIter pod_iter; GtkTreeIter iter; int i; if (store_podcast_get_pod_iter(&pod_iter, pt->podcast) != 0) { return FALSE; } i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &iter, &pod_iter, i++)) { gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter, MS_COL_DATA, &item, -1); if (pt->item == item) { store_podcast_remove_podcast_item(&iter); break; } } free(pt); store_podcast_save(); return FALSE; } void store_podcast_update_podcast(podcast_download_t * pd) { aqualung_idle_add(store_podcast_update_podcast_cb, pd); } void store_podcast_update_podcast_download(podcast_download_t * pd) { aqualung_idle_add(store_podcast_update_podcast_download_cb, pd); } void store_podcast_add_item(podcast_t * podcast, podcast_item_t * item) { podcast_transfer_t * pt = podcast_transfer_new(podcast, item); if (pt != NULL) { aqualung_idle_add(store_podcast_add_item_cb, pt); } } void store_podcast_remove_item(podcast_t * podcast, podcast_item_t * item) { podcast_transfer_t * pt = podcast_transfer_new(podcast, item); if (pt != NULL) { aqualung_idle_add(store_podcast_remove_item_cb, pt); } } static void set_comment_text(GtkTreeIter * tree_iter, GtkTextIter * text_iter, GtkTextBuffer * buffer) { char * comment = NULL; void * data; GtkTreePath * path; int level; path = gtk_tree_model_get_path(GTK_TREE_MODEL(music_store), tree_iter); level = gtk_tree_path_get_depth(path); gtk_tree_path_free(path); gtk_tree_model_get(GTK_TREE_MODEL(music_store), tree_iter, MS_COL_DATA, &data, -1); switch (level) { case 2: comment = ((podcast_t *)data)->desc; break; case 3: comment = ((podcast_item_t *)data)->desc; break; } if (comment != NULL && comment[0] != '\0') { gtk_text_buffer_insert(buffer, text_iter, comment, -1); } } static void item_status_bar_info(GtkTreeModel * model, GtkTreeIter * iter, double * size, float * length, int * nnewitem) { podcast_item_t * item; gtk_tree_model_get(model, iter, MS_COL_DATA, &item, -1); *size += item->size / 1024.0; *length += item->duration; if (item->new) { *nnewitem += 1; } } static void feed_status_bar_info(GtkTreeModel * model, GtkTreeIter * iter, double * size, float * length, int * nnewitem, int * nitem) { GtkTreeIter track_iter; int i = 0; while (gtk_tree_model_iter_nth_child(model, &track_iter, iter, i++)) { item_status_bar_info(model, &track_iter, size, length, nnewitem); } *nitem += i - 1; } static void store_status_bar_info(GtkTreeModel * model, GtkTreeIter * iter, double * size, float * length, int * nnewitem, int * nitem, int * nfeed) { GtkTreeIter record_iter; int i = 0; while (gtk_tree_model_iter_nth_child(model, &record_iter, iter, i++)) { feed_status_bar_info(model, &record_iter, size, length, nnewitem, nitem); } *nfeed = i - 1; } static void set_status_bar_info(GtkTreeIter * tree_iter, GtkLabel * statusbar) { int nnewitem = 0, nitem = 0, nfeed = 0; float length = 0.0f; double size = 0.0; podcast_t * podcast; char str[MAXLEN]; char length_str[MAXLEN]; char tmp[MAXLEN]; char * name; GtkTreeModel * model = GTK_TREE_MODEL(music_store); GtkTreePath * path; int depth; path = gtk_tree_model_get_path(model, tree_iter); depth = gtk_tree_path_get_depth(path); gtk_tree_path_free(path); gtk_tree_model_get(model, tree_iter, MS_COL_NAME, &name, -1); switch (depth) { case 3: item_status_bar_info(model, tree_iter, &size, &length, &nnewitem); sprintf(str, "%s ", name); break; case 2: gtk_tree_model_get(model, tree_iter, MS_COL_DATA, &podcast, -1); podcast_get_display_name(podcast, tmp); feed_status_bar_info(model, tree_iter, &size, &length, &nnewitem, &nitem); if (nnewitem > 0) { sprintf(str, "%s: %d %s, %d %s ", tmp, nitem, (nitem == 1) ? _("item") : _("items"), nnewitem, (nnewitem == 1) ? _("new item") : _("new items")); } else { sprintf(str, "%s: %d %s ", tmp, nitem, (nitem == 1) ? _("item") : _("items")); } break; case 1: store_status_bar_info(model, tree_iter, &size, &length, &nnewitem, &nitem, &nfeed); if (nnewitem > 0) { sprintf(str, "%s: %d %s, %d %s, %d %s ", name, nfeed, (nfeed == 1) ? _("feed") : _("feeds"), nitem, (nitem == 1) ? _("item") : _("items"), nnewitem, (nnewitem == 1) ? _("new item") : _("new items")); } else { sprintf(str, "%s: %d %s, %d %s ", name, nfeed, (nfeed == 1) ? _("feed") : _("feeds"), nitem, (nitem == 1) ? _("item") : _("items")); } break; } g_free(name); if (length > 0.0f || nitem == 0) { time2time(length, length_str); sprintf(tmp, " [%s] ", length_str); } else { strcpy(tmp, " [N/A] "); } strcat(str, tmp); if (options.ms_statusbar_show_size) { if (size > 1024 * 1024) { sprintf(tmp, " (%.1f GB) ", size / (1024 * 1024)); } else if (size > 1024) { sprintf(tmp, " (%.1f MB) ", size / 1024); } else if (size > 0 || nitem == 0) { sprintf(tmp, " (%.1f KB) ", size); } else { strcpy(tmp, " (N/A) "); } strcat(str, tmp); } gtk_label_set_text(statusbar, str); } static void set_popup_sensitivity(GtkTreePath * path) { int depth = gtk_tree_path_get_depth(path); GtkTreeIter iter; gtk_tree_model_get_iter(GTK_TREE_MODEL(music_store), &iter, path); if (depth == 2) { podcast_t * podcast; gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter, MS_COL_DATA, &podcast, -1); gtk_widget_set_sensitive(podcast_feed__edit, podcast->state == PODCAST_STATE_IDLE); gtk_widget_set_sensitive(podcast_feed__remove, podcast->state == PODCAST_STATE_IDLE); gtk_widget_set_sensitive(podcast_feed__abort, podcast->state != PODCAST_STATE_ABORTED); if (podcast->state != PODCAST_STATE_IDLE) { gtk_widget_hide(podcast_feed__update); gtk_widget_show(podcast_feed__abort); } else { gtk_widget_show(podcast_feed__update); gtk_widget_hide(podcast_feed__abort); } } if (depth == 1) { int n = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(music_store), &iter); gtk_widget_set_sensitive(podcast_store__update, n > 0); gtk_widget_set_sensitive(podcast_store__reorder, n > 1); gtk_widget_set_sensitive(podcast_store__update_enabled, n > 0); } } static void add_path_to_playlist(GtkTreePath * path, GtkTreeIter * piter, int new_tab) { int depth = gtk_tree_path_get_depth(path); gtk_tree_selection_select_path(music_select, path); if (new_tab) { GtkTreeIter iter; gtk_tree_model_get_iter(GTK_TREE_MODEL(music_store), &iter, path); if (depth == 2) { char name[MAXLEN]; podcast_t * podcast; gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter, MS_COL_DATA, &podcast, -1); podcast_get_display_name(podcast, name); playlist_tab_new_if_nonempty(name); } else { char * name; gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter, MS_COL_NAME, &name, -1); playlist_tab_new_if_nonempty(name); g_free(name); } } switch (depth) { case 1: podcast_store__addlist_defmode(piter); break; case 2: podcast_feed__addlist_defmode(piter); break; case 3: podcast_track__addlist_cb(piter); break; } } /*************************************************/ /* music store interface */ int store_podcast_iter_is_track(GtkTreeIter * iter) { GtkTreePath * p = gtk_tree_model_get_path(GTK_TREE_MODEL(music_store), iter); int ret = (gtk_tree_path_get_depth(p) == 3); gtk_tree_path_free(p); return ret; } void store_podcast_iter_addlist_defmode(GtkTreeIter * ms_iter, GtkTreeIter * pl_iter, int new_tab) { GtkTreePath * p = gtk_tree_model_get_path(GTK_TREE_MODEL(music_store), ms_iter); add_path_to_playlist(p, pl_iter, new_tab); gtk_tree_path_free(p); } void store_podcast_selection_changed(GtkTreeIter * tree_iter, GtkTextBuffer * buffer, GtkLabel * statusbar) { GtkTextIter text_iter; gtk_text_buffer_get_iter_at_offset(buffer, &text_iter, 0); set_comment_text(tree_iter, &text_iter, buffer); if (options.enable_mstore_statusbar) { set_status_bar_info(tree_iter, statusbar); } } gboolean store_podcast_event_cb(GdkEvent * event, GtkTreeIter * iter, GtkTreePath * path) { if (event->type == GDK_BUTTON_PRESS) { GdkEventButton * bevent = (GdkEventButton *)event; if (bevent->button == 3) { set_popup_sensitivity(path); switch (gtk_tree_path_get_depth(path)) { case 1: gtk_menu_popup(GTK_MENU(podcast_store_menu), NULL, NULL, NULL, NULL, bevent->button, bevent->time); break; case 2: gtk_menu_popup(GTK_MENU(podcast_feed_menu), NULL, NULL, NULL, NULL, bevent->button, bevent->time); break; case 3: gtk_menu_popup(GTK_MENU(podcast_track_menu), NULL, NULL, NULL, NULL, bevent->button, bevent->time); break; } } } if (event->type == GDK_KEY_PRESS) { GdkEventKey * kevent = (GdkEventKey *) event; int i; switch (gtk_tree_path_get_depth(path)) { case 1: for (i = 0; podcast_store_keybinds[i].callback; ++i) { if ((podcast_store_keybinds[i].state == 0 && kevent->state == 0) || podcast_store_keybinds[i].state & kevent->state) { if (kevent->keyval == podcast_store_keybinds[i].keyval1 || kevent->keyval == podcast_store_keybinds[i].keyval2) { (podcast_store_keybinds[i].callback)(NULL); } } } break; case 2: for (i = 0; podcast_feed_keybinds[i].callback; ++i) { if ((podcast_feed_keybinds[i].state == 0 && kevent->state == 0) || podcast_feed_keybinds[i].state & kevent->state) { if (kevent->keyval == podcast_feed_keybinds[i].keyval1 || kevent->keyval == podcast_feed_keybinds[i].keyval2) { (podcast_feed_keybinds[i].callback)(NULL); } } } break; case 3: for (i = 0; podcast_track_keybinds[i].callback; ++i) { if ((podcast_track_keybinds[i].state == 0 && kevent->state == 0) || podcast_track_keybinds[i].state & kevent->state) { if (kevent->keyval == podcast_track_keybinds[i].keyval1 || kevent->keyval == podcast_track_keybinds[i].keyval2) { (podcast_track_keybinds[i].callback)(NULL); } } } break; } } return FALSE; } void store_podcast_load_icons(void) { char path[MAXLEN]; sprintf(path, "%s/%s", AQUALUNG_DATADIR, "ms-podcast.png"); icon_podcasts = gdk_pixbuf_new_from_file (path, NULL); sprintf(path, "%s/%s", AQUALUNG_DATADIR, "ms-feed.png"); icon_feed = gdk_pixbuf_new_from_file (path, NULL); } void store_podcast_create_popup_menu(void) { GtkWidget * separator; /* create popup menu for podcast_track tree items */ podcast_track_menu = gtk_menu_new(); register_toplevel_window(podcast_track_menu, TOP_WIN_SKIN); podcast_track__addlist = gtk_menu_item_new_with_label(_("Add to playlist")); #ifdef HAVE_EXPORT podcast_track__export = gtk_menu_item_new_with_label(_("Export item...")); #endif /* HAVE_EXPORT */ podcast_track__fileinfo = gtk_menu_item_new_with_label(_("File info...")); gtk_menu_shell_append(GTK_MENU_SHELL(podcast_track_menu), podcast_track__addlist); #ifdef HAVE_EXPORT gtk_menu_shell_append(GTK_MENU_SHELL(podcast_track_menu), podcast_track__export); #endif /* HAVE_EXPORT */ gtk_menu_shell_append(GTK_MENU_SHELL(podcast_track_menu), podcast_track__fileinfo); g_signal_connect_swapped(G_OBJECT(podcast_track__addlist), "activate", G_CALLBACK(podcast_track__addlist_cb), NULL); #ifdef HAVE_EXPORT g_signal_connect_swapped(G_OBJECT(podcast_track__export), "activate", G_CALLBACK(podcast_track__export_cb), NULL); #endif /* HAVE_EXPORT */ g_signal_connect_swapped(G_OBJECT(podcast_track__fileinfo), "activate", G_CALLBACK(podcast_track__fileinfo_cb), NULL); gtk_widget_show(podcast_track__addlist); #ifdef HAVE_EXPORT gtk_widget_show(podcast_track__export); #endif /* HAVE_EXPORT */ gtk_widget_show(podcast_track__fileinfo); /* create popup menu for podcast_feed tree items */ podcast_feed_menu = gtk_menu_new(); register_toplevel_window(podcast_feed_menu, TOP_WIN_SKIN); podcast_feed__addlist = gtk_menu_item_new_with_label(_("Add all items to playlist")); podcast_feed__addlist_albummode = gtk_menu_item_new_with_label(_("Add all items to playlist (Album mode)")); podcast_feed__addlist_new = gtk_menu_item_new_with_label(_("Add new items to playlist")); podcast_feed__addlist_albummode_new = gtk_menu_item_new_with_label(_("Add new items to playlist (Album mode)")); podcast_feed__subscribe = gtk_menu_item_new_with_label(_("Subscribe to new feed")); podcast_feed__edit = gtk_menu_item_new_with_label(_("Edit feed")); #ifdef HAVE_EXPORT podcast_feed__export = gtk_menu_item_new_with_label(_("Export all items...")); podcast_feed__export_new = gtk_menu_item_new_with_label(_("Export new items...")); #endif /* HAVE_EXPORT */ podcast_feed__update = gtk_menu_item_new_with_label(_("Update feed")); podcast_feed__abort = gtk_menu_item_new_with_label(_("Abort ongoing update")); podcast_feed__remove = gtk_menu_item_new_with_label(_("Remove feed")); gtk_menu_shell_append(GTK_MENU_SHELL(podcast_feed_menu), podcast_feed__addlist_new); gtk_menu_shell_append(GTK_MENU_SHELL(podcast_feed_menu), podcast_feed__addlist_albummode_new); separator = gtk_separator_menu_item_new(); gtk_menu_shell_append(GTK_MENU_SHELL(podcast_feed_menu), separator); gtk_widget_show(separator); gtk_menu_shell_append(GTK_MENU_SHELL(podcast_feed_menu), podcast_feed__addlist); gtk_menu_shell_append(GTK_MENU_SHELL(podcast_feed_menu), podcast_feed__addlist_albummode); separator = gtk_separator_menu_item_new(); gtk_menu_shell_append(GTK_MENU_SHELL(podcast_feed_menu), separator); gtk_widget_show(separator); gtk_menu_shell_append(GTK_MENU_SHELL(podcast_feed_menu), podcast_feed__subscribe); gtk_menu_shell_append(GTK_MENU_SHELL(podcast_feed_menu), podcast_feed__edit); gtk_menu_shell_append(GTK_MENU_SHELL(podcast_feed_menu), podcast_feed__update); gtk_menu_shell_append(GTK_MENU_SHELL(podcast_feed_menu), podcast_feed__abort); gtk_menu_shell_append(GTK_MENU_SHELL(podcast_feed_menu), podcast_feed__remove); separator = gtk_separator_menu_item_new(); gtk_menu_shell_append(GTK_MENU_SHELL(podcast_feed_menu), separator); gtk_widget_show(separator); #ifdef HAVE_EXPORT gtk_menu_shell_append(GTK_MENU_SHELL(podcast_feed_menu), podcast_feed__export_new); gtk_menu_shell_append(GTK_MENU_SHELL(podcast_feed_menu), podcast_feed__export); #endif /* HAVE_EXPORT */ g_signal_connect_swapped(G_OBJECT(podcast_feed__addlist), "activate", G_CALLBACK(podcast_feed__addlist_cb), NULL); g_signal_connect_swapped(G_OBJECT(podcast_feed__addlist_albummode), "activate", G_CALLBACK(podcast_feed__addlist_albummode_cb), NULL); g_signal_connect_swapped(G_OBJECT(podcast_feed__addlist_new), "activate", G_CALLBACK(podcast_feed__addlist_new_cb), NULL); g_signal_connect_swapped(G_OBJECT(podcast_feed__addlist_albummode_new), "activate", G_CALLBACK(podcast_feed__addlist_albummode_new_cb), NULL); g_signal_connect_swapped(G_OBJECT(podcast_feed__subscribe), "activate", G_CALLBACK(podcast_feed__subscribe_cb), NULL); g_signal_connect_swapped(G_OBJECT(podcast_feed__edit), "activate", G_CALLBACK(podcast_feed__edit_cb), NULL); #ifdef HAVE_EXPORT g_signal_connect_swapped(G_OBJECT(podcast_feed__export), "activate", G_CALLBACK(podcast_feed__export_cb), (gpointer)0); g_signal_connect_swapped(G_OBJECT(podcast_feed__export_new), "activate", G_CALLBACK(podcast_feed__export_cb), (gpointer)1); #endif /* HAVE_EXPORT */ g_signal_connect_swapped(G_OBJECT(podcast_feed__update), "activate", G_CALLBACK(podcast_feed__update_cb), NULL); g_signal_connect_swapped(G_OBJECT(podcast_feed__abort), "activate", G_CALLBACK(podcast_feed__abort_cb), NULL); g_signal_connect_swapped(G_OBJECT(podcast_feed__remove), "activate", G_CALLBACK(podcast_feed__remove_cb), NULL); gtk_widget_show(podcast_feed__addlist); gtk_widget_show(podcast_feed__addlist_albummode); gtk_widget_show(podcast_feed__addlist_new); gtk_widget_show(podcast_feed__addlist_albummode_new); gtk_widget_show(podcast_feed__subscribe); gtk_widget_show(podcast_feed__edit); #ifdef HAVE_EXPORT gtk_widget_show(podcast_feed__export); gtk_widget_show(podcast_feed__export_new); #endif /* HAVE_EXPORT */ gtk_widget_show(podcast_feed__update); gtk_widget_show(podcast_feed__remove); /* create popup menu for podcast_store tree items */ podcast_store_menu = gtk_menu_new(); register_toplevel_window(podcast_store_menu, TOP_WIN_SKIN); podcast_store__addlist = gtk_menu_item_new_with_label(_("Add all items to playlist")); podcast_store__addlist_albummode = gtk_menu_item_new_with_label(_("Add all items to playlist (Album mode)")); podcast_store__addlist_new = gtk_menu_item_new_with_label(_("Add new items to playlist")); podcast_store__addlist_albummode_new = gtk_menu_item_new_with_label(_("Add new items to playlist (Album mode)")); podcast_store__subscribe = gtk_menu_item_new_with_label(_("Subscribe to new feed")); podcast_store__update = gtk_menu_item_new_with_label(_("Update all feeds")); podcast_store__reorder = gtk_menu_item_new_with_label(_("Reorder feeds")); #ifdef HAVE_EXPORT podcast_store__export = gtk_menu_item_new_with_label(_("Export all items...")); podcast_store__export_new = gtk_menu_item_new_with_label(_("Export new items...")); #endif /* HAVE_EXPORT */ podcast_store__update_enabled = gtk_check_menu_item_new_with_label(_("Automatically update feeds")); gtk_menu_shell_append(GTK_MENU_SHELL(podcast_store_menu), podcast_store__addlist_new); gtk_menu_shell_append(GTK_MENU_SHELL(podcast_store_menu), podcast_store__addlist_albummode_new); separator = gtk_separator_menu_item_new(); gtk_menu_shell_append(GTK_MENU_SHELL(podcast_store_menu), separator); gtk_widget_show(separator); gtk_menu_shell_append(GTK_MENU_SHELL(podcast_store_menu), podcast_store__addlist); gtk_menu_shell_append(GTK_MENU_SHELL(podcast_store_menu), podcast_store__addlist_albummode); separator = gtk_separator_menu_item_new(); gtk_menu_shell_append(GTK_MENU_SHELL(podcast_store_menu), separator); gtk_widget_show(separator); gtk_menu_shell_append(GTK_MENU_SHELL(podcast_store_menu), podcast_store__subscribe); gtk_menu_shell_append(GTK_MENU_SHELL(podcast_store_menu), podcast_store__update); gtk_menu_shell_append(GTK_MENU_SHELL(podcast_store_menu), podcast_store__reorder); separator = gtk_separator_menu_item_new(); gtk_menu_shell_append(GTK_MENU_SHELL(podcast_store_menu), separator); gtk_widget_show(separator); #ifdef HAVE_EXPORT gtk_menu_shell_append(GTK_MENU_SHELL(podcast_store_menu), podcast_store__export_new); gtk_menu_shell_append(GTK_MENU_SHELL(podcast_store_menu), podcast_store__export); #endif /* HAVE_EXPORT */ separator = gtk_separator_menu_item_new(); gtk_menu_shell_append(GTK_MENU_SHELL(podcast_store_menu), separator); gtk_widget_show(separator); gtk_menu_shell_append(GTK_MENU_SHELL(podcast_store_menu), podcast_store__update_enabled); g_signal_connect_swapped(G_OBJECT(podcast_store__addlist), "activate", G_CALLBACK(podcast_store__addlist_cb), NULL); g_signal_connect_swapped(G_OBJECT(podcast_store__addlist_albummode), "activate", G_CALLBACK(podcast_store__addlist_albummode_cb), NULL); g_signal_connect_swapped(G_OBJECT(podcast_store__addlist_new), "activate", G_CALLBACK(podcast_store__addlist_new_cb), NULL); g_signal_connect_swapped(G_OBJECT(podcast_store__addlist_albummode_new), "activate", G_CALLBACK(podcast_store__addlist_albummode_new_cb), NULL); g_signal_connect_swapped(G_OBJECT(podcast_store__subscribe), "activate", G_CALLBACK(podcast_feed__subscribe_cb), NULL); g_signal_connect_swapped(G_OBJECT(podcast_store__update), "activate", G_CALLBACK(podcast_store__update_cb), NULL); g_signal_connect_swapped(G_OBJECT(podcast_store__reorder), "activate", G_CALLBACK(podcast_store__reorder_cb), NULL); #ifdef HAVE_EXPORT g_signal_connect_swapped(G_OBJECT(podcast_store__export), "activate", G_CALLBACK(podcast_store__export_cb), (gpointer)0); g_signal_connect_swapped(G_OBJECT(podcast_store__export_new), "activate", G_CALLBACK(podcast_store__export_cb), (gpointer)1); #endif /* HAVE_EXPORT */ g_signal_connect_swapped(G_OBJECT(podcast_store__update_enabled), "activate", G_CALLBACK(podcast_store__update_enabled_cb), NULL); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(podcast_store__update_enabled), options.podcasts_autocheck); gtk_widget_show(podcast_store__addlist); gtk_widget_show(podcast_store__addlist_albummode); gtk_widget_show(podcast_store__addlist_new); gtk_widget_show(podcast_store__addlist_albummode_new); gtk_widget_show(podcast_store__subscribe); gtk_widget_show(podcast_store__update); gtk_widget_show(podcast_store__reorder); #ifdef HAVE_EXPORT gtk_widget_show(podcast_store__export); gtk_widget_show(podcast_store__export_new); #endif /* HAVE_EXPORT */ gtk_widget_show(podcast_store__update_enabled); } void store_podcast_set_toolbar_sensitivity(GtkTreeIter * iter, GtkWidget * edit, GtkWidget * add, GtkWidget * remove) { GtkTreePath * p = gtk_tree_model_get_path(GTK_TREE_MODEL(music_store), iter); int depth = gtk_tree_path_get_depth(p); gtk_widget_set_sensitive(edit, depth == 2); gtk_widget_set_sensitive(add, depth < 3); gtk_widget_set_sensitive(remove, depth == 2); gtk_tree_path_free(p); } void store_podcast_toolbar__edit_cb(gpointer data) { podcast_feed__edit_cb(NULL); } void store_podcast_toolbar__add_cb(gpointer data) { podcast_feed__subscribe_cb(NULL); } void store_podcast_toolbar__remove_cb(gpointer data) { podcast_feed__remove_cb(NULL); } void create_podcast_node(void) { GtkTreeIter iter; store_t * data; if ((data = (store_t *)malloc(sizeof(store_t))) == NULL) { fprintf(stderr, "create_podcast_node: malloc error\n"); return; } data->type = STORE_TYPE_PODCAST; gtk_tree_store_insert(music_store, &iter, NULL, 0); gtk_tree_store_set(music_store, &iter, MS_COL_NAME, _("Podcasts"), MS_COL_SORT, "001", MS_COL_FONT, PANGO_WEIGHT_BOLD, MS_COL_DATA, data, -1); if (options.enable_ms_tree_icons) { gtk_tree_store_set(music_store, &iter, MS_COL_ICON, icon_podcasts, -1); } } gboolean store_podcast_updater_cb(gpointer data) { if (options.podcasts_autocheck) { podcast_store__update_cb((gpointer)1); } return TRUE; } void store_podcast_updater_start(void) { store_podcast_updater_cb(NULL); aqualung_timeout_add(5*60*1000, store_podcast_updater_cb, NULL); } /*************************************************/ void save_podcast_item(xmlDocPtr doc, xmlNodePtr root, GtkTreeIter * iter) { xmlNodePtr node; podcast_item_t * item; char * sort; gtk_tree_model_get(GTK_TREE_MODEL(music_store), iter, MS_COL_SORT, &sort, MS_COL_DATA, &item, -1); node = xmlNewTextChild(root, NULL, (const xmlChar *) "item", NULL); xml_save_str(node, "file", item->file); xml_save_str(node, "title", item->title); xml_save_str(node, "desc", item->desc); xml_save_str(node, "url", item->url); xml_save_str(node, "sort", sort); xml_save_int(node, "new", item->new); xml_save_float(node, "duration", item->duration); xml_save_uint(node, "size", item->size); xml_save_uint(node, "date", item->date); g_free(sort); } void save_podcast(xmlDocPtr doc, xmlNodePtr root, GtkTreeIter * pod_iter) { xmlNodePtr node; podcast_t * podcast; GtkTreeIter iter; int i; gtk_tree_model_get(GTK_TREE_MODEL(music_store), pod_iter, MS_COL_DATA, &podcast, -1); node = xmlNewTextChild(root, NULL, (const xmlChar *) "channel", NULL); xml_save_str(node, "dir", podcast->dir); xml_save_str(node, "title", podcast->title); xml_save_str(node, "author", podcast->author); xml_save_str(node, "desc", podcast->desc); xml_save_str(node, "url", podcast->url); xml_save_int(node, "flags", podcast->flags); xml_save_uint(node, "check_interval", podcast->check_interval); xml_save_uint(node, "last_checked", podcast->last_checked); xml_save_uint(node, "count_limit", podcast->count_limit); xml_save_uint(node, "date_limit", podcast->date_limit); xml_save_uint(node, "size_limit", podcast->size_limit); i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &iter, pod_iter, i++)) { save_podcast_item(doc, node, &iter); } } void store_podcast_save(void) { xmlDocPtr doc; xmlNodePtr root; int i; GtkTreeIter iter_store; GtkTreeIter pod_iter; char file[MAXLEN]; if (store_podcast_get_store_iter(&iter_store) != 0) { return; } doc = xmlNewDoc((const xmlChar *) "1.0"); root = xmlNewNode(NULL, (const xmlChar *) "aqualung_podcast"); xmlDocSetRootElement(doc, root); i = 0; while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &pod_iter, &iter_store, i++)) { save_podcast(doc, root, &pod_iter); } snprintf(file, MAXLEN-1, "%s/podcast.xml", options.confdir); xmlSaveFormatFile(file, doc, 1); xmlFreeDoc(doc); music_store_selection_changed(STORE_TYPE_PODCAST); } void parse_podcast_item(xmlDocPtr doc, xmlNodePtr cur, GtkTreeIter * pod_iter, podcast_t * podcast) { GtkTreeIter iter; podcast_item_t * item; char sort[MAXLEN]; if ((item = podcast_item_new()) == NULL) { return; } podcast->items = g_slist_prepend(podcast->items, item); gtk_tree_store_append(music_store, &iter, pod_iter); gtk_tree_store_set(music_store, &iter, MS_COL_NAME, "", MS_COL_SORT, "", MS_COL_DATA, item, -1); if (options.enable_ms_tree_icons) { gtk_tree_store_set(music_store, &iter, MS_COL_ICON, icon_track, -1); } for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) { xml_load_str_dup(doc, cur, "file", &item->file); xml_load_str_dup(doc, cur, "title", &item->title); xml_load_str_dup(doc, cur, "desc", &item->desc); xml_load_str_dup(doc, cur, "url", &item->url); xml_load_str(doc, cur, "sort", sort); xml_load_int(doc, cur, "new", &item->new); xml_load_float(doc, cur, "duration", &item->duration); xml_load_uint(doc, cur, "size", &item->size); xml_load_uint(doc, cur, "date", &item->date); } if (item->new) { gtk_tree_store_set(music_store, &iter, MS_COL_FONT, PANGO_WEIGHT_BOLD, -1); } gtk_tree_store_set(music_store, &iter, MS_COL_NAME, item->title, -1); gtk_tree_store_set(music_store, &iter, MS_COL_SORT, sort, -1); } void parse_podcast(xmlDocPtr doc, xmlNodePtr cur, GtkTreeIter * iter_store) { GtkTreeIter pod_iter; podcast_t * podcast; if ((podcast = podcast_new()) == NULL) { return; } gtk_tree_store_append(music_store, &pod_iter, iter_store); gtk_tree_store_set(music_store, &pod_iter, MS_COL_NAME, "", MS_COL_SORT, "", MS_COL_DATA, podcast, -1); if (options.enable_ms_tree_icons) { gtk_tree_store_set(music_store, &pod_iter, MS_COL_ICON, icon_feed, -1); } for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) { xml_load_str_dup(doc, cur, "dir", &podcast->dir); xml_load_str_dup(doc, cur, "title", &podcast->title); xml_load_str_dup(doc, cur, "author", &podcast->author); xml_load_str_dup(doc, cur, "desc", &podcast->desc); xml_load_str_dup(doc, cur, "url", &podcast->url); xml_load_int(doc, cur, "flags", &podcast->flags); xml_load_uint(doc, cur, "check_interval", &podcast->check_interval); xml_load_uint(doc, cur, "last_checked", &podcast->last_checked); xml_load_uint(doc, cur, "count_limit", &podcast->count_limit); xml_load_uint(doc, cur, "date_limit", &podcast->date_limit); xml_load_uint(doc, cur, "size_limit", &podcast->size_limit); if (!xmlStrcmp(cur->name, (const xmlChar *)"item")) { parse_podcast_item(doc, cur, &pod_iter, podcast); } } podcast_iter_set_display_name(podcast, &pod_iter); } void store_podcast_load(void) { GtkTreeIter iter_store; xmlDocPtr doc; xmlNodePtr cur; char file[MAXLEN]; snprintf(file, MAXLEN-1, "%s/podcast.xml", options.confdir); if (!g_file_test(file, G_FILE_TEST_EXISTS)) { return; } if (store_podcast_get_store_iter(&iter_store) != 0) { return; } doc = xmlParseFile(file); if (doc == NULL) { fprintf(stderr, "An XML error occured while parsing %s\n", file); return; } cur = xmlDocGetRootElement(doc); if (cur == NULL) { fprintf(stderr, "store_file_load: empty XML document\n"); xmlFreeDoc(doc); return; } if (xmlStrcmp(cur->name, (const xmlChar *)"aqualung_podcast")) { fprintf(stderr, "store_file_load: XML document of the wrong type, " "root node != aqualung_podcast\n"); xmlFreeDoc(doc); return; } for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) { if (!xmlStrcmp(cur->name, (const xmlChar *)"channel")) { parse_podcast(doc, cur, &iter_store); } } xmlFreeDoc(doc); } #endif /* HAVE_PODCAST */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/transceiver.c0000644000175000001440000001055511243310700014367 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: transceiver.c 1067 2009-07-24 09:35:15Z peterszilagyi $ */ #include #include #include #include #include #include #include #include #include #include #include "common.h" #include "transceiver.h" int aqualung_socket_fd; char aqualung_socket_filename[256]; int aqualung_session_id; int create_socket(const char * filename) { struct sockaddr_un name; int sock; size_t size; sock = socket(PF_LOCAL, SOCK_DGRAM, 0); if (sock < 0) { perror("create_socket(): socket"); return -1; } name.sun_family = AF_LOCAL; strncpy(name.sun_path, filename, sizeof(name.sun_path)); size = SUN_LEN(&name); if (bind(sock, (struct sockaddr *)&name, size) < 0) { perror("create_socket(): bind"); return -1; } return sock; } char receive_message(int fd, char * cmdarg) { fd_set set; struct timeval tv; struct sockaddr_un name; size_t size; int n_read; char buffer[MAXLEN]; char rcmd; int i; FD_ZERO(&set); FD_SET(fd, &set); tv.tv_sec = 0; tv.tv_usec = 0; if (select(fd + 1, &set, NULL, NULL, &tv) <= 0) return 0; size = sizeof(name); n_read = recvfrom(fd, buffer, MAXLEN-1, 0, (struct sockaddr *)&name, (socklen_t *)&size); buffer[n_read] = '\0'; rcmd = buffer[0]; switch (rcmd) { case RCMD_PING: break; case RCMD_BACK: case RCMD_PLAY: case RCMD_PAUSE: case RCMD_STOP: case RCMD_FWD: case RCMD_QUIT: return rcmd; case RCMD_VOLADJ: case RCMD_ADD_FILE: strncpy(cmdarg, buffer + 1, MAXLEN-2); return rcmd; case RCMD_ADD_COMMIT: for (i = 1; i <= 3; i++) { cmdarg[i-1] = buffer[i]; } cmdarg[3] = '\0'; strncpy(cmdarg + 3, buffer + 4, MAXLEN-5); return rcmd; default: fprintf(stderr, "Recv'd unrecognized remote command %d\n", rcmd); break; } return 0; } int send_message(const char * filename, char * message, int len) { char tempsockname[MAXLEN]; int sock; struct sockaddr_un name; int nbytes; struct timespec req_time; struct timespec rem_time; req_time.tv_sec = 0; req_time.tv_nsec = 100000000; sprintf(tempsockname, "/tmp/aqualung_%s.tmp", g_get_user_name()); sock = create_socket(tempsockname); name.sun_family = AF_LOCAL; strcpy(name.sun_path, filename); do { nbytes = sendto(sock, message, len+1, 0, (struct sockaddr *)&name, sizeof(name)); if (nbytes == -1 && errno == ENOBUFS) { nanosleep(&req_time, &rem_time); } } while (nbytes == -1 && errno == ENOBUFS); remove(tempsockname); close(sock); return nbytes; } int send_message_to_session_report_error(int session_id, char * message, int len, int report_error) { char name[MAXLEN]; int nbytes = 0; sprintf(name, "/tmp/aqualung_%s.%d", g_get_user_name(), session_id); if((nbytes = send_message(name, message, len)) < 0 && report_error) { perror("send_message(): sendto"); } return nbytes; } void send_message_to_session(int session_id, char * message, int len) { send_message_to_session_report_error(session_id, message, len, 1); } void setup_app_socket(void) { int sock = -1; int i; char name[MAXLEN]; char rcmd = RCMD_PING; for (i=0; sock == -1; i++) { if (send_message_to_session_report_error(i, &rcmd, 1, 0) < 0) { sprintf(name, "/tmp/aqualung_%s.%d", g_get_user_name(), i); unlink(name); sock = create_socket(name); } } aqualung_socket_fd = sock; aqualung_session_id = --i; strncpy(aqualung_socket_filename, name, 255); } void close_app_socket(void) { remove(aqualung_socket_filename); close(aqualung_socket_fd); } // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/transceiver.h0000644000175000001440000000323710730024026014376 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: transceiver.h 916 2007-12-11 09:23:24Z tszilagyi $ */ #ifndef _TRANSCEIVER_H #define _TRANSCEIVER_H /* valid remote command codes */ #define RCMD_PING 1 #define RCMD_BACK 2 #define RCMD_PLAY 3 #define RCMD_PAUSE 4 #define RCMD_STOP 5 #define RCMD_FWD 6 #define RCMD_ADD_FILE 7 #define RCMD_ADD_COMMIT 8 #define RCMD_QUIT 9 #define RCMD_VOLADJ 10 int create_socket(const char * filename); char receive_message(int fd, char * cmd_arg); void setup_app_socket(void); void close_app_socket(void); int send_message(const char * filename, char * message, int len); void send_message_to_session(int session_id, char * message, int len); int send_message_to_session_report_error(int session_id, char * message, int len, int report_error); #endif /* _TRANSCEIVER_H */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/trashlist.c0000644000175000001440000000361010612341733014062 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: trashlist.c 524 2007-01-06 15:39:18Z pasp $ */ #include #include #include #include "common.h" #include "trashlist.h" trashlist_t * trashlist_new(void) { trashlist_t * root; if ((root = (trashlist_t *)malloc(sizeof(trashlist_t))) == NULL) { fprintf(stderr, "trashlist.c : trashlist_new(): malloc error\n"); return NULL; } root->ptr = NULL; root->next = NULL; return root; } void trashlist_add(trashlist_t * root, void * ptr) { trashlist_t * q_item = NULL; trashlist_t * q_prev; if ((q_item = (trashlist_t *)malloc(sizeof(trashlist_t))) == NULL) { fprintf(stderr, "trashlist.c : trashlist_add(): malloc error\n"); return; } q_item->ptr = ptr; q_item->next = NULL; q_prev = root; while (q_prev->next != NULL) { q_prev = q_prev->next; } q_prev->next = q_item; } void trashlist_free(trashlist_t * root) { trashlist_t * p; trashlist_t * q; if (root == NULL) return; p = root->next; while (p != NULL) { q = p->next; free(p->ptr); free(p); p = q; } free(root); } // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/trashlist.h0000644000175000001440000000230110661105505014062 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: trashlist.h 777 2007-08-16 17:34:02Z tszilagyi $ */ #ifndef _TRASHLIST_H #define _TRASHLIST_H typedef struct _trashlist_t { void * ptr; struct _trashlist_t * next; } trashlist_t; trashlist_t * trashlist_new(void); void trashlist_add(trashlist_t * root, void * ptr); void trashlist_free(trashlist_t * root); #endif /* _TRASHLIST_H */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/utils.c0000644000175000001440000003040411136163152013205 00000000000000/* -*- linux-c -*- Copyright (C) 2007 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: utils.c 1045 2008-12-25 13:10:34Z peterszilagyi $ */ #include #include #include #include #include #include #include #include "i18n.h" #include "httpc.h" #include "utils.h" extern options_t options; float convf(char * s) { float val, pow; int i, sign; for (i = 0; s[i] == ' ' || s[i] == '\n' || s[i] == '\t'; i++); sign = 1; if (s[i] == '+' || s[i] == '-') sign = (s[i++] == '+') ? 1 : -1; for (val = 0; s[i] >= '0' && s[i] <= '9'; i++) val = 10 * val + s[i] - '0'; if ((s[i] == '.') || (s[i] == ',')) i++; for (pow = 1; s[i] >= '0' && s[i] <= '9'; i++) { val = 10 * val + s[i] - '0'; pow *= 10; } return(sign * val / pow); } int is_all_wspace(char * str) { int i; if (str == NULL) { return 1; } for (i = 0; str[i]; i++) { if (str[i] != ' ' && str[i] != '\t') { return 0; } } return 1; } int cut_trailing_whitespace(char * str) { int i = strlen(str) - 1; while (i >= 0) { if ((str[i] == ' ') || (str[i] == '\t')) { str[i] = '\0'; } else { break; } --i; } return ((i >= 0) ? 1 : 0); } /* To print a string containing printf formatters, but * *not* followed by arguments -- I just want the plain * string, please... */ void escape_percents(char * in, char * out) { int i; int j = 0; for (i = 0; in[i] != '\0'; i++) { out[j] = in[i]; ++j; if (in[i] == '%') { out[j] = '%'; ++j; } } out[j] = '\0'; } int contains(int * cbuf, int num, char c) { int n; for (n = 0; n < num; ++n) { if (c == cbuf[n]) { return n; } } return -1; } /* returns 0: success -1: error: expected '{' after '?' -2: error: expected '}' after '{' -3: error: unknown conversion type character after '%' -4: error: unknown conversion type character after '?' */ int make_string_va(char * buf, char * format, ...) { va_list args; char ** strbuf = NULL; int * cbuf = NULL; int ch; int num = 0; int i, j, n, conj, disj; va_start(args, format); while ((ch = va_arg(args, int)) != 0) { char * p; ++num; cbuf = (int *)realloc(cbuf, num * sizeof(int)); cbuf[num-1] = ch; strbuf = (char **)realloc(strbuf, num * sizeof(char *)); p = va_arg(args, char *); strbuf[num-1] = (p != NULL) ? strdup(p) : NULL; } va_end(args); cbuf = (int *)realloc(cbuf, (num + 3) * sizeof(int)); strbuf = (char **)realloc(strbuf, (num + 3) * sizeof(char *)); cbuf[num] = '%'; strbuf[num] = strdup("%"); ++num; cbuf[num] = '?'; strbuf[num] = strdup("?"); ++num; cbuf[num] = '}'; strbuf[num] = strdup("}"); ++num; i = 0; j = 0; while (format[i]) { switch (format[i]) { case '%': if ((n = contains(cbuf, num, format[i+1])) < 0) { return -3; } else { if (strbuf[n]) { buf[j] = '\0'; strcat(buf, strbuf[n]); j = strlen(buf); } i += 2; } break; case '?': disj = 0; conj = 1; for (++i; format[i]; ++i) { if (format[i] == '|' || format[i] == '{') { disj = disj || conj; conj = 1; } else { if ((n = contains(cbuf, num, format[i])) < 0) { return -4; } else { conj = conj && (strbuf[n] != NULL); } } if (format[i] == '{') { break; } } if (!format[i]) { return -1; } ++i; while (format[i] && format[i] != '}') { if (format[i] == '%') { if ((n = contains(cbuf, num, format[i+1])) < 0) { return -3; } else { if (disj && strbuf[n]) { buf[j] = '\0'; strcat(buf, strbuf[n]); j = strlen(buf); } i += 2; } } else { if (disj) { buf[j++] = format[i]; } ++i; } } if (!format[i]) { return -2; } ++i; break; default: buf[j++] = format[i++]; break; } } buf[j] = '\0'; for (n = 0; n < num; n++) { if (strbuf[n] != NULL) { free(strbuf[n]); } } free(cbuf); free(strbuf); return 0; } void make_title_string(char * dest, char * templ, char * artist, char * record, char * track) { make_string_va(dest, templ, 'a', artist, 'r', record, 't', track, 0); } void make_string_strerror(int ret, char * buf) { switch (ret) { case -1: strncpy(buf, _("Unexpected end of string after '?'."), MAXLEN-1); break; case -2: strncpy(buf, _("Expected '}' after '{', but end of string found."), MAXLEN-1); break; case -3: strncpy(buf, _("Unknown conversion type character found after '%%%%'."), MAXLEN-1); break; case -4: strncpy(buf, _("Unknown conversion type character found after '?'."), MAXLEN-1); break; } } /* returns (hh:mm:ss) or (mm:ss) format time string from sample position */ void sample2time(unsigned long SR, unsigned long long sample, char * str, int sign) { int h; char m, s; if (!SR) SR = 1; h = (sample / SR) / 3600; m = (sample / SR) / 60 - h * 60; s = (sample / SR) - h * 3600 - m * 60; if (h > 0) { sprintf(str, (sign)?("-%d:%02d:%02d"):("%d:%02d:%02d"), h, m, s); } else { sprintf(str, (sign)?("-%02d:%02d"):("%02d:%02d"), m, s); } } /* converts a length measured in seconds to the appropriate string */ void time2time(float seconds, char * str) { int d, h; char m, s; d = seconds / 86400; h = seconds / 3600; m = seconds / 60 - h * 60; s = seconds - h * 3600 - m * 60; h = h - d * 24; if (d > 0) { if (d == 1 && h > 9) { sprintf(str, "%d %s, %2d:%02d:%02d", d, _("day"), h, m, s); } else if (d == 1 && h < 9) { sprintf(str, "%d %s, %1d:%02d:%02d", d, _("day"), h, m, s); } else if (d != 1 && h > 9) { sprintf(str, "%d %s, %2d:%02d:%02d", d, _("days"), h, m, s); } else { sprintf(str, "%d %s, %1d:%02d:%02d", d, _("days"), h, m, s); } } else if (h > 0) { if (h > 9) { sprintf(str, "%02d:%02d:%02d", h, m, s); } else { sprintf(str, "%1d:%02d:%02d", h, m, s); } } else { sprintf(str, "%02d:%02d", m, s); } } void time2time_na(float seconds, char * str) { if (seconds == 0.0) { strcpy(str, "N/A"); } else { time2time(seconds, str); } } /* out should be defined as char[MAXLEN] */ void normalize_filename(const char * in, char * out) { if (httpc_is_url(in)) { strncpy(out, in, MAXLEN-1); return; } switch (in[0]) { case '/': strncpy(out, in, MAXLEN-1); break; case '~': snprintf(out, MAXLEN-1, "%s%s", options.home, in + 1); break; default: snprintf(out, MAXLEN-1, "%s/%s", options.cwd, in); break; } } void free_strdup(char ** s, const char * str) { if (*s != NULL) { free(*s); } if (str != NULL) { *s = strdup(str); } else { *s = NULL; } } int is_valid_year(int y) { return y >= YEAR_MIN && y <= YEAR_MAX; } int cdda_is_cdtrack(char * file) { return (strstr(file, "CDDA ") == file); } int is_dir(char * path) { struct stat st_file; if (stat(path, &st_file) == -1) { return 0; } return S_ISDIR(st_file.st_mode); } #ifndef HAVE_STRNDUP char * strndup(char * str, size_t len) { char * dup = (char *)malloc(len + 1); if (dup) { strncpy(dup, str, len); dup[len] = '\0'; } return dup; } #endif /* HAVE_STRNDUP */ #ifndef HAVE_STRCASESTR char toupper(char c) { if (c >= 'a' && c <= 'z') return (c-32); return c; } char * strcasestr(char *haystack, char *needle) { char *s1 = needle; char *s2 = haystack; char *sr = NULL; int inside = 0; while (*s2 != '\0') { if (toupper(*s1) == toupper(*s2)) { if (inside == 0) { sr = s2; } inside = 1; ++s1; ++s2; if (*s1 == '\0') { break; } } else { inside = 0; s1 = needle; ++s2; } } if (inside == 1) return sr; return NULL; } #endif /* HAVE_STRCASESTR */ map_t * map_new(char * str) { map_t * map; if ((map = (map_t *)malloc(sizeof(map_t))) == NULL) { fprintf(stderr, "map_new(): malloc error\n"); return NULL; } strncpy(map->str, str, MAXLEN-1); map->count = 1; map->next = NULL; return map; } void map_put(map_t ** map, char * str) { map_t * pmap; map_t * _pmap; if (str == NULL || str[0] == '\0') { return; } if (*map == NULL) { *map = map_new(str); } else { for (_pmap = pmap = *map; pmap; _pmap = pmap, pmap = pmap->next) { char * key1 = g_utf8_casefold(str, -1); char * key2 = g_utf8_casefold(pmap->str, -1); if (!g_utf8_collate(key1, key2)) { pmap->count++; g_free(key1); g_free(key2); return; } g_free(key1); g_free(key2); } _pmap->next = map_new(str); } } char * map_get_max(map_t * map) { map_t * pmap; int max = 0; char * str = NULL; for (pmap = map; pmap; pmap = pmap->next) { if (max <= pmap->count) { str = pmap->str; max = pmap->count; } } return str; } void map_free(map_t * map) { map_t * pmap; for (pmap = map; pmap; map = pmap) { pmap = map->next; free(map); } } void xml_save_str(xmlNodePtr node, char * varname, char * var) { xmlNewTextChild(node, NULL, (const xmlChar *)varname, (xmlChar *)var); } void xml_save_int(xmlNodePtr node, char * varname, int var) { char str[32]; snprintf(str, 31, "%d", var); xmlNewTextChild(node, NULL, (const xmlChar *)varname, (xmlChar *)str); } void xml_save_uint(xmlNodePtr node, char * varname, unsigned var) { char str[32]; snprintf(str, 31, "%u", var); xmlNewTextChild(node, NULL, (const xmlChar *)varname, (xmlChar *)str); } void xml_save_float(xmlNodePtr node, char * varname, float var) { char str[32]; snprintf(str, 31, "%.1f", var); xmlNewTextChild(node, NULL, (const xmlChar *)varname, (xmlChar *)str); } void xml_save_int_array(xmlNodePtr node, char * varname, int * var, int idx) { char name[MAXLEN]; snprintf(name, MAXLEN-1, "%s_%d", varname, idx); xml_save_int(node, name, var[idx]); } void xml_load_str(xmlDocPtr doc, xmlNodePtr node, char * varname, char * var) { if (!xmlStrcmp(node->name, (const xmlChar *)varname)) { xmlChar * key = xmlNodeListGetString(doc, node->xmlChildrenNode, 1); if (key != NULL) { strncpy(var, (char *)key, MAXLEN-1); xmlFree(key); } } } void xml_load_str_dup(xmlDocPtr doc, xmlNodePtr node, char * varname, char ** var) { if (!xmlStrcmp(node->name, (const xmlChar *)varname)) { xmlChar * key = xmlNodeListGetString(doc, node->xmlChildrenNode, 1); if (key != NULL) { *var = strdup((char *)key); xmlFree(key); } } } void xml_load_int(xmlDocPtr doc, xmlNodePtr node, char * varname, int * var) { if ((!xmlStrcmp(node->name, (const xmlChar *)varname))) { xmlChar * key = xmlNodeListGetString(doc, node->xmlChildrenNode, 1); if (key != NULL) { sscanf((char *)key, "%d", var); xmlFree(key); } } } void xml_load_uint(xmlDocPtr doc, xmlNodePtr node, char * varname, unsigned * var) { if ((!xmlStrcmp(node->name, (const xmlChar *)varname))) { xmlChar * key = xmlNodeListGetString(doc, node->xmlChildrenNode, 1); if (key != NULL) { sscanf((char *)key, "%u", var); xmlFree(key); } } } void xml_load_float(xmlDocPtr doc, xmlNodePtr node, char * varname, float * var) { if ((!xmlStrcmp(node->name, (const xmlChar *)varname))) { xmlChar * key = xmlNodeListGetString(doc, node->xmlChildrenNode, 1); if (key != NULL) { sscanf((char *)key, "%f", var); xmlFree(key); } } } void xml_load_int_array(xmlDocPtr doc, xmlNodePtr node, char * varname, int * var, int idx) { char name[MAXLEN]; snprintf(name, MAXLEN-1, "%s_%d", varname, idx); xml_load_int(doc, node, name, var + idx); } // vim: shiftwidth=8:tabstop=8:softtabstop=8: aqualung-0.9beta11/src/utils.h0000644000175000001440000000605110736426776013236 00000000000000/* -*- linux-c -*- Copyright (C) 2007 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: utils.h 973 2008-01-01 11:16:27Z peterszilagyi $ */ #ifndef _UTILS_H #define _UTILS_H #include #include #include #include "common.h" /* Please update when we reach the 22nd century. */ #define YEAR_MIN 1900 #define YEAR_MAX 2100 float convf(char * s); int cut_trailing_whitespace(char * str); void escape_percents(char * in, char * out); int make_string_va(char * buf, char * format, ...); void make_title_string(char * dest, char * templ, char * artist, char * record, char * track); void make_string_strerror(int ret, char * buf); void sample2time(unsigned long SR, unsigned long long sample, char * str, int sign); void time2time(float samples, char * str); void time2time_na(float seconds, char * str); void normalize_filename(const char * in, char * out); void free_strdup(char ** s, const char * str); int is_valid_year(int y); int is_all_wspace(char * str); int cdda_is_cdtrack(char * file); int is_dir(char * path); #ifndef HAVE_STRNDUP char * strndup(char * str, size_t len); #endif /* HAVE_STRNDUP */ #ifndef HAVE_STRCASESTR char * strcasestr(char * haystack, char * needle); #endif /* HAVE_STRCASESTR */ typedef struct _map_t { char str[MAXLEN]; int count; struct _map_t * next; } map_t; void map_put(map_t ** map, char * str); char * map_get_max(map_t * map); void map_free(map_t * map); void xml_save_str(xmlNodePtr node, char * varname, char * var); void xml_save_int(xmlNodePtr node, char * varname, int var); void xml_save_uint(xmlNodePtr node, char * varname, unsigned var); void xml_save_float(xmlNodePtr node, char * varname, float var); void xml_save_int_array(xmlNodePtr node, char * varname, int * var, int idx); void xml_load_str(xmlDocPtr doc, xmlNodePtr node, char * varname, char * var); void xml_load_str_dup(xmlDocPtr doc, xmlNodePtr node, char * varname, char ** var); void xml_load_int(xmlDocPtr doc, xmlNodePtr node, char * varname, int * var); void xml_load_uint(xmlDocPtr doc, xmlNodePtr node, char * varname, unsigned * var); void xml_load_float(xmlDocPtr doc, xmlNodePtr node, char * varname, float * var); void xml_load_int_array(xmlDocPtr doc, xmlNodePtr node, char * varname, int * var, int idx); #endif /* _UTILS_H */ // vim: shiftwidth=8:tabstop=8:softtabstop=8: aqualung-0.9beta11/src/utils_gui.c0000644000175000001440000005714711324131225014061 00000000000000/* -*- linux-c -*- Copyright (C) 2007 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: utils_gui.c 1092 2010-01-03 15:58:59Z peterszilagyi $ */ #include #include #include #include #include #include "common.h" #include "i18n.h" #include "options.h" #include "utils.h" #include "utils_gui.h" extern options_t options; #ifdef HAVE_SNDFILE extern char * valid_extensions_sndfile[]; #endif /* HAVE_SNDFILE */ #ifdef HAVE_MPEG extern char * valid_extensions_mpeg[]; #endif /* HAVE_MPEG */ #ifdef HAVE_MOD extern char * valid_extensions_mod[]; #endif /* HAVE_MOD */ #if GTK_CHECK_VERSION(2,12,0) #define NEW_TOOLTIP_API #endif /* GTK_CHECK_VERSION */ #ifndef NEW_TOOLTIP_API /* tooltips group */ GtkTooltips * aqualung_tooltips; #endif /* !NEW_TOOLTIP_API */ GSList * toplevel_windows; typedef struct { GtkWidget * window; int flag; } top_win_t; void unregister_toplevel_window(GtkWidget * window) { GSList * node; for (node = toplevel_windows; node; node = node->next) { top_win_t * tw = (top_win_t *)node->data; if (tw->window == window) { toplevel_windows = g_slist_remove(toplevel_windows, tw); free(tw); break; } } } void register_toplevel_window(GtkWidget * window, int flag) { top_win_t * tw; if ((tw = (top_win_t *)calloc(1, sizeof(top_win_t))) == NULL) { fprintf(stderr, "register_toplevel_window: calloc error\n"); return; } tw->window = window; tw->flag = flag; unregister_toplevel_window(window); toplevel_windows = g_slist_append(toplevel_windows, tw); } void toplevel_window_foreach(int flag, void (* callback)(GtkWidget * window)) { GSList * node; for (node = toplevel_windows; node; node = node->next) { top_win_t * tw = (top_win_t *)node->data; if (tw->flag & flag) { callback(tw->window); } } } #ifdef HAVE_SYSTRAY int systray_semaphore = 0; int get_systray_semaphore() { return systray_semaphore; } #endif /* HAVE_SYSTRAY */ gint aqualung_dialog_run(GtkDialog * dialog) { #ifdef HAVE_SYSTRAY int ret; systray_semaphore++; gtk_window_present(GTK_WINDOW(dialog)); ret = gtk_dialog_run(dialog); systray_semaphore--; return ret; #else gtk_window_present(GTK_WINDOW(dialog)); return gtk_dialog_run(dialog); #endif /* HAVE_SYSTRAY */ } typedef struct { GSourceFunc func; gpointer data; GDestroyNotify destroy; } threads_dispatch_t; static gboolean threads_dispatch(gpointer data) { threads_dispatch_t * dispatch = data; gboolean ret = FALSE; GDK_THREADS_ENTER(); if (!g_source_is_destroyed(g_main_current_source())) { ret = dispatch->func(dispatch->data); } GDK_THREADS_LEAVE(); return ret; } static void threads_dispatch_free(gpointer data) { threads_dispatch_t * dispatch = data; if (dispatch->destroy && dispatch->data) { dispatch->destroy(dispatch->data); } g_slice_free(threads_dispatch_t, data); } guint aqualung_idle_add(GSourceFunc function, gpointer data) { threads_dispatch_t * dispatch; dispatch = g_slice_new(threads_dispatch_t); dispatch->func = function; dispatch->data = data; dispatch->destroy = NULL; return g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, threads_dispatch, dispatch, threads_dispatch_free); } guint aqualung_timeout_add(guint interval, GSourceFunc function, gpointer data) { threads_dispatch_t * dispatch; dispatch = g_slice_new(threads_dispatch_t); dispatch->func = function; dispatch->data = data; dispatch->destroy = NULL; #if GLIB_CHECK_VERSION(2,14,0) if (interval % 1000 == 0) { return g_timeout_add_seconds_full(G_PRIORITY_DEFAULT, interval / 1000, threads_dispatch, dispatch, threads_dispatch_free); } #endif return g_timeout_add_full(G_PRIORITY_DEFAULT, interval, threads_dispatch, dispatch, threads_dispatch_free); } void aqualung_tooltips_init(void) { #ifndef NEW_TOOLTIP_API aqualung_tooltips = gtk_tooltips_new(); #endif /* !NEW_TOOLTIP_API */ } void aqualung_tooltips_set_enabled(gboolean enabled) { #ifdef NEW_TOOLTIP_API GtkSettings * settings = gtk_settings_get_default(); if (settings != NULL) { g_object_set(settings, "gtk-enable-tooltips", enabled, NULL); } #else if (enabled) { gtk_tooltips_enable(aqualung_tooltips); } else { gtk_tooltips_disable(aqualung_tooltips); } #endif } #ifdef HAVE_SYSTRAY void aqualung_status_icon_set_tooltip_text(GtkStatusIcon * icon, const gchar * text) { #if GTK_CHECK_VERSION(2,16,0) gtk_status_icon_set_tooltip_text(icon, text); #else gtk_status_icon_set_tooltip(icon, text); #endif /* GTK_CHECK_VERSION */ } #endif /* HAVE_SYSTRAY */ void aqualung_widget_set_tooltip_text(GtkWidget * widget, const gchar * text) { #ifdef NEW_TOOLTIP_API gtk_widget_set_tooltip_text(widget, text); #else gtk_tooltips_set_tip(GTK_TOOLTIPS(aqualung_tooltips), widget, text, NULL); #endif } /* create button with stock item * * in: label - label for button (label=NULL to disable label, label=-1 to disable button relief) * stock - stock icon identifier */ GtkWidget* gui_stock_label_button(gchar *label, const gchar *stock) { GtkWidget *button; GtkWidget *alignment; GtkWidget *hbox; GtkWidget *image; button = g_object_new (GTK_TYPE_BUTTON, "visible", TRUE, NULL); if (label== (gchar *)-1) { gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE); } alignment = gtk_alignment_new (0.5, 0.5, 0.0, 0.0); hbox = gtk_hbox_new (FALSE, 2); gtk_container_add (GTK_CONTAINER (alignment), hbox); image = gtk_image_new_from_stock (stock, GTK_ICON_SIZE_BUTTON); if (image) { gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, TRUE, 0); } if (label != NULL && label != (gchar *)-1) { gtk_box_pack_start (GTK_BOX (hbox), g_object_new (GTK_TYPE_LABEL, "label", label, "use_underline", TRUE, NULL), FALSE, TRUE, 0); } gtk_widget_show_all (alignment); gtk_container_add (GTK_CONTAINER (button), alignment); return button; } void assign_etf_fc_filters(GtkFileChooser *fc) { GtkFileFilter *filter_1, *filter_2; /* all files filter */ filter_1 = gtk_file_filter_new(); gtk_file_filter_add_pattern(filter_1, "*"); gtk_file_filter_set_name(GTK_FILE_FILTER(filter_1), _("All Files")); gtk_file_chooser_add_filter(fc, filter_1); /* music store files filter */ filter_2 = gtk_file_filter_new(); gtk_file_filter_add_pattern(filter_2, "*.[lL][uU][aA]"); gtk_file_filter_set_name(GTK_FILE_FILTER(filter_2), _("Extended Title Format Files (*.lua)")); gtk_file_chooser_add_filter(fc, filter_2); gtk_file_chooser_set_filter(fc, filter_2); } void assign_store_fc_filters(GtkFileChooser *fc) { GtkFileFilter *filter_1, *filter_2; /* all files filter */ filter_1 = gtk_file_filter_new(); gtk_file_filter_add_pattern(filter_1, "*"); gtk_file_filter_set_name(GTK_FILE_FILTER(filter_1), _("All Files")); gtk_file_chooser_add_filter(fc, filter_1); /* music store files filter */ filter_2 = gtk_file_filter_new(); gtk_file_filter_add_pattern(filter_2, "*.[xX][mM][lL]"); gtk_file_filter_set_name(GTK_FILE_FILTER(filter_2), _("Music Store Files (*.xml)")); gtk_file_chooser_add_filter(fc, filter_2); gtk_file_chooser_set_filter(fc, filter_2); } void assign_playlist_fc_filters(GtkFileChooser *fc) { gchar *file_filters[] = { _("Aqualung playlist (*.xml)"), "*.[xX][mM][lL]", _("MP3 Playlist (*.m3u)"), "*.[mM]3[uU]", _("Multimedia Playlist (*.pls)"), "*.[pP][lL][sS]", }; gint i, len; GtkFileFilter *filter_1, *filter_2, *filter_3; len = sizeof(file_filters)/sizeof(gchar*)/2; /* all files filter */ filter_1 = gtk_file_filter_new(); gtk_file_filter_add_pattern(filter_1, "*"); gtk_file_filter_set_name(GTK_FILE_FILTER(filter_1), _("All Files")); gtk_file_chooser_add_filter(fc, filter_1); /* all playlist files filter */ filter_2 = gtk_file_filter_new(); for (i = 0; i < len; i++) { gtk_file_filter_add_pattern(filter_2, file_filters[2*i+1]); } gtk_file_filter_set_name(GTK_FILE_FILTER(filter_2), _("All Playlist Files")); gtk_file_chooser_add_filter(fc, filter_2); gtk_file_chooser_set_filter(fc, filter_2); /* single extensions */ for (i = 0; i < len; i++) { filter_3 = gtk_file_filter_new(); gtk_file_filter_add_pattern(filter_3, file_filters[2*i+1]); gtk_file_filter_set_name(GTK_FILE_FILTER(filter_3), file_filters[2*i]); gtk_file_chooser_add_filter(fc, filter_3); } } void build_filter_from_extensions(GtkFileFilter * f1, GtkFileFilter * f2, char * extensions[]) { int i, j, k; for (i = 0; extensions[i]; i++) { char buf[32]; buf[0] = '*'; buf[1] = '.'; k = 2; for (j = 0; extensions[i][j]; j++) { if (isalpha(extensions[i][j]) && k < 28) { buf[k++] = '['; buf[k++] = tolower(extensions[i][j]); buf[k++] = toupper(extensions[i][j]); buf[k++] = ']'; } else if (k < 31) { buf[k++] = extensions[i][j]; } } buf[k] = '\0'; gtk_file_filter_add_pattern(f1, buf); gtk_file_filter_add_pattern(f2, buf); } } void assign_audio_fc_filters(GtkFileChooser * fc) { GtkFileFilter * filter; GtkFileFilter * filter_all; filter = gtk_file_filter_new(); gtk_file_filter_set_name(filter, _("All Files")); gtk_file_filter_add_pattern(filter, "*"); gtk_file_chooser_add_filter(fc, filter); filter_all = gtk_file_filter_new(); gtk_file_filter_set_name(filter_all, _("All Audio Files")); gtk_file_chooser_add_filter(fc, filter_all); gtk_file_chooser_set_filter(fc, filter_all); #ifdef HAVE_SNDFILE filter = gtk_file_filter_new(); gtk_file_filter_set_name(filter, _("Sound Files (*.wav, *.aiff, *.au, ...)")); build_filter_from_extensions(filter, filter_all, valid_extensions_sndfile); gtk_file_chooser_add_filter(fc, filter); #endif /* HAVE_SNDFILE */ #ifdef HAVE_FLAC filter = gtk_file_filter_new(); gtk_file_filter_set_name(filter, _("Free Lossless Audio Codec (*.flac)")); gtk_file_filter_add_pattern(filter, "*.[fF][lL][aA][cC]"); gtk_file_filter_add_pattern(filter_all, "*.[fF][lL][aA][cC]"); gtk_file_chooser_add_filter(fc, filter); #endif /* HAVE_FLAC */ #ifdef HAVE_MPEG filter = gtk_file_filter_new(); gtk_file_filter_set_name(filter, _("MPEG Audio (*.mp3, *.mpa, *.mpega, ...)")); build_filter_from_extensions(filter, filter_all, valid_extensions_mpeg); gtk_file_chooser_add_filter(fc, filter); #endif /* HAME_MPEG */ #ifdef HAVE_OGG_VORBIS filter = gtk_file_filter_new(); gtk_file_filter_set_name(filter, _("Ogg Vorbis (*.ogg)")); gtk_file_filter_add_pattern(filter, "*.[oO][gG][gG]"); gtk_file_filter_add_pattern(filter_all, "*.[oO][gG][gG]"); gtk_file_chooser_add_filter(fc, filter); #endif /* HAVE_OGG_VORBIS */ #ifdef HAVE_SPEEX filter = gtk_file_filter_new(); gtk_file_filter_set_name(filter, _("Ogg Speex (*.spx)")); gtk_file_filter_add_pattern(filter, "*.[sS][pP][xX]"); gtk_file_filter_add_pattern(filter_all, "*.[sS][pP][xX]"); gtk_file_chooser_add_filter(fc, filter); #endif /* HAVE_SPEEX */ #ifdef HAVE_MPC filter = gtk_file_filter_new(); gtk_file_filter_set_name(filter, _("Musepack (*.mpc)")); gtk_file_filter_add_pattern(filter, "*.[mM][pP][cC]"); gtk_file_filter_add_pattern(filter_all, "*.[mM][pP][cC]"); gtk_file_chooser_add_filter(fc, filter); #endif /* HAVE_MPC */ #ifdef HAVE_MAC filter = gtk_file_filter_new(); gtk_file_filter_set_name(filter, _("Monkey's Audio Codec (*.ape)")); gtk_file_filter_add_pattern(filter, "*.[aA][pP][eE]"); gtk_file_filter_add_pattern(filter_all, "*.[aA][pP][eE]"); gtk_file_chooser_add_filter(fc, filter); #endif /* HAVE_MAC */ #ifdef HAVE_MOD filter = gtk_file_filter_new(); gtk_file_filter_set_name(filter, _("Modules (*.xm, *.mod, *.it, *.s3m, ...)")); build_filter_from_extensions(filter, filter_all, valid_extensions_mod); gtk_file_chooser_add_filter(fc, filter); #endif /* HAVE_MOD */ #if defined(HAVE_MOD) && (defined(HAVE_LIBZ) || defined(HAVE_LIBBZ2)) filter = gtk_file_filter_new(); #if defined(HAVE_LIBZ) && defined(HAVE_LIBBZ2) gtk_file_filter_set_name(filter, _("Compressed modules (*.gz, *.bz2)")); #elif defined(HAVE_LIBZ) gtk_file_filter_set_name(filter, _("Compressed modules (*.gz)")); #elif defined(HAVE_LIBBZ2) gtk_file_filter_set_name(filter, _("Compressed modules (*.bz2)")); #endif /* HAVE_LIBZ, HAVE_LIBBZ2 */ #ifdef HAVE_LIBZ gtk_file_filter_add_pattern(filter, "*.[gG][zZ]"); gtk_file_filter_add_pattern(filter_all, "*.[gG][zZ]"); #endif /* HAVE_LIBZ */ #ifdef HAVE_LIBBZ2 gtk_file_filter_add_pattern(filter, "*.[bB][zZ]2"); gtk_file_filter_add_pattern(filter_all, "*.[bB][zZ]2"); #endif /* HAVE_LIBBZ2 */ gtk_file_chooser_add_filter(fc, filter); #endif /* (HAVE_MOD && HAVE LIBZ) */ #ifdef HAVE_WAVPACK filter = gtk_file_filter_new(); gtk_file_filter_set_name(filter, _("WavPack (*.wv)")); gtk_file_filter_add_pattern(filter, "*.[wW][vV]"); gtk_file_filter_add_pattern(filter_all, "*.[wW][vV]"); gtk_file_chooser_add_filter(fc, filter); #endif /* HAVE_WAVPACK */ #ifdef HAVE_LAVC filter = gtk_file_filter_new(); gtk_file_filter_set_name(filter, _("LAVC audio/video files")); { char * valid_ext_lavc[] = { "aac", "ac3", "asf", "avi", "mpeg", "mpg", "mp3", "ra", "wav", "wma", "wv", NULL }; build_filter_from_extensions(filter, filter_all, valid_ext_lavc); } gtk_file_chooser_add_filter(fc, filter); #endif /* HAVE_LAVC */ } void assign_fc_filters(GtkFileChooser * fc, int filter) { gtk_widget_realize(GTK_WIDGET(fc)); if (filter == FILE_CHOOSER_FILTER_AUDIO) { assign_audio_fc_filters(fc); } if (filter == FILE_CHOOSER_FILTER_PLAYLIST) { assign_playlist_fc_filters(fc); } if (filter == FILE_CHOOSER_FILTER_STORE) { assign_store_fc_filters(fc); } if (filter == FILE_CHOOSER_FILTER_ETF) { assign_etf_fc_filters(fc); } } GSList * file_chooser(char * title, GtkWidget * parent, GtkFileChooserAction action, int filter, gint multiple, char * destpath) { GtkWidget * dialog; GSList * files = NULL; dialog = gtk_file_chooser_dialog_new(title, GTK_WINDOW(parent), action, (action == GTK_FILE_CHOOSER_ACTION_SAVE) ? GTK_STOCK_SAVE : GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL); gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER); gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), multiple); gtk_file_chooser_select_filename(GTK_FILE_CHOOSER(dialog), destpath); if (action == GTK_FILE_CHOOSER_ACTION_SAVE) { char * bname = g_path_get_basename(destpath); gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), bname); g_free(bname); } gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT); assign_fc_filters(GTK_FILE_CHOOSER(dialog), filter); if (options.show_hidden) { gtk_file_chooser_set_show_hidden(GTK_FILE_CHOOSER(dialog), TRUE); } if (aqualung_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { strncpy(destpath, gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)), MAXLEN-1); files = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog)); } gtk_widget_destroy(dialog); return files; } void file_chooser_with_entry(char * title, GtkWidget * parent, GtkFileChooserAction action, int filter, GtkWidget * entry, char * destpath) { GtkWidget * dialog; const gchar * selected_filename = gtk_entry_get_text(GTK_ENTRY(entry)); char path[MAXLEN]; path[0] = '\0'; dialog = gtk_file_chooser_dialog_new(title, GTK_WINDOW(parent), action, GTK_STOCK_APPLY, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL); if (options.show_hidden) { gtk_file_chooser_set_show_hidden(GTK_FILE_CHOOSER(dialog), options.show_hidden); } if (strlen(selected_filename)) { char * filename = g_filename_from_utf8(selected_filename, -1, NULL, NULL, NULL); if (filename == NULL) { gtk_widget_destroy(dialog); return; } normalize_filename(filename, path); g_free(filename); } else { strncpy(path, destpath, MAXLEN-1); } gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), path); if (action == GTK_FILE_CHOOSER_ACTION_SAVE) { char * bname = g_path_get_basename(path); gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), bname); g_free(bname); } gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER_ON_PARENT); gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT); assign_fc_filters(GTK_FILE_CHOOSER(dialog), filter); if (aqualung_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { char * utf8; selected_filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); utf8 = g_filename_to_utf8(selected_filename, -1, NULL, NULL, NULL); if (utf8 == NULL) { gtk_widget_destroy(dialog); } gtk_entry_set_text(GTK_ENTRY(entry), utf8); strncpy(destpath, selected_filename, MAXLEN-1); g_free(utf8); } gtk_widget_destroy(dialog); } int message_dialog(char * title, GtkWidget * parent, GtkMessageType type, GtkButtonsType buttons, GtkWidget * extra, char * text, ...) { GtkWidget * dialog; va_list args; gchar * msg = NULL; int res; va_start(args, text); msg = g_strdup_vprintf(text, args); va_end(args); dialog = gtk_message_dialog_new(GTK_WINDOW(parent), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, type, buttons, "%s", msg); g_free(msg); if (extra != NULL) { gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), extra, FALSE, FALSE, 5); gtk_widget_show_all(extra); } gtk_window_set_title(GTK_WINDOW(dialog), title); res = aqualung_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); return res; } void insert_label_entry(GtkWidget * table, char * ltext, GtkWidget ** entry, char * etext, int y1, int y2, gboolean editable) { GtkWidget * label; GtkWidget * hbox; label = gtk_label_new(ltext); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(table), hbox, 0, 1, y1, y2, GTK_FILL, GTK_FILL, 5, 5); *entry = gtk_entry_new(); gtk_entry_set_max_length(GTK_ENTRY(*entry), MAXLEN-1); gtk_editable_set_editable(GTK_EDITABLE (*entry), editable ? TRUE : FALSE); if (etext != NULL) { gtk_entry_set_text(GTK_ENTRY(*entry), etext); } gtk_table_attach(GTK_TABLE(table), *entry, 1, 2, y1, y2, GTK_FILL | GTK_EXPAND, GTK_FILL, 0, 5); } void insert_label_entry_button(GtkWidget * table, char * ltext, GtkWidget ** entry, char * etext, GtkWidget * button, int y1, int y2) { GtkWidget * label; GtkWidget * hbox; label = gtk_label_new(ltext); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(table), hbox, 0, 1, y1, y2, GTK_FILL, GTK_FILL, 5, 5); hbox = gtk_hbox_new(FALSE, 0); gtk_table_attach(GTK_TABLE(table), hbox, 1, 2, y1, y2, GTK_FILL | GTK_EXPAND, GTK_FILL, 0, 5); *entry = gtk_entry_new(); gtk_entry_set_max_length(GTK_ENTRY(*entry), MAXLEN-1); if (etext != NULL) { gtk_entry_set_text(GTK_ENTRY(*entry), etext); } gtk_box_pack_start(GTK_BOX(hbox), *entry, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, TRUE, 5); } void insert_label_entry_browse(GtkWidget * table, char * ltext, GtkWidget ** entry, char * etext, int y1, int y2, void (* browse_cb)(GtkButton * button, gpointer data)) { GtkWidget * button = gui_stock_label_button(_("_Browse..."), GTK_STOCK_OPEN); insert_label_entry_button(table, ltext, entry, etext, button, y1, y2); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(browse_cb), *entry); } void insert_label_progbar_button(GtkWidget * table, char * ltext, GtkWidget ** progbar, GtkWidget * button, int y1, int y2) { GtkWidget * label; GtkWidget * hbox; label = gtk_label_new(ltext); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(table), hbox, 0, 1, y1, y2, GTK_FILL, GTK_FILL, 5, 5); hbox = gtk_hbox_new(FALSE, 0); gtk_table_attach(GTK_TABLE(table), hbox, 1, 2, y1, y2, GTK_FILL | GTK_EXPAND, GTK_FILL, 0, 5); *progbar = gtk_progress_bar_new(); gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(*progbar), 0.0f); gtk_progress_bar_set_text(GTK_PROGRESS_BAR(*progbar), "0%"); gtk_box_pack_start(GTK_BOX(hbox), *progbar, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, TRUE, 5); } void insert_label_spin(GtkWidget * table, char * ltext, GtkWidget ** spin, int spinval, int y1, int y2) { GtkWidget * label; GtkWidget * hbox; label = gtk_label_new(ltext); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(table), hbox, 0, 1, y1, y2, GTK_FILL, GTK_FILL, 5, 5); *spin = gtk_spin_button_new_with_range(YEAR_MIN, YEAR_MAX, 1); gtk_spin_button_set_value(GTK_SPIN_BUTTON(*spin), spinval); gtk_table_attach(GTK_TABLE(table), *spin, 1, 2, y1, y2, GTK_EXPAND | GTK_FILL, GTK_FILL, 2, 5); } void insert_label_spin_with_limits(GtkWidget * table, char * ltext, GtkWidget ** spin, double spinval, double min, double max, int y1, int y2) { insert_label_spin(table, ltext, spin, spinval, y1, y2); gtk_spin_button_set_range(GTK_SPIN_BUTTON(*spin), min, max); gtk_spin_button_set_value(GTK_SPIN_BUTTON(*spin), spinval); } void set_option_from_toggle(GtkWidget * widget, int * opt) { if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) { *opt = 1; } else { *opt = 0; } } void set_option_from_combo(GtkWidget * widget, int * opt) { *opt = gtk_combo_box_get_active(GTK_COMBO_BOX(widget)); } void set_option_from_spin(GtkWidget * widget, int * opt) { *opt = gtk_spin_button_get_value(GTK_SPIN_BUTTON(widget)); } void set_option_from_entry(GtkWidget * widget, char * opt, int n) { strncpy(opt, gtk_entry_get_text(GTK_ENTRY(widget)), n-1); } void set_option_bit_from_toggle(GtkWidget * toggle, int * opt, int bit) { if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toggle))) { *opt |= bit; } else { *opt &= ~bit; } } // vim: shiftwidth=8:tabstop=8:softtabstop=8: aqualung-0.9beta11/src/utils_gui.h0000644000175000001440000000717311316415632014070 00000000000000/* -*- linux-c -*- Copyright (C) 2007 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: utils_gui.h 1091 2009-12-29 11:22:48Z peterszilagyi $ */ #ifndef _UTILS_GUI_H #define _UTILS_GUI_H #include #include enum { TOP_WIN_SKIN = (1 << 0), TOP_WIN_TRAY = (1 << 1) }; void register_toplevel_window(GtkWidget * window, int flag); void unregister_toplevel_window(GtkWidget * window); void toplevel_window_foreach(int flag, void (* callback)(GtkWidget * window)); enum { FILE_CHOOSER_FILTER_NONE = 0, FILE_CHOOSER_FILTER_AUDIO, FILE_CHOOSER_FILTER_PLAYLIST, FILE_CHOOSER_FILTER_STORE, FILE_CHOOSER_FILTER_ETF }; #ifdef HAVE_SYSTRAY int get_systray_semaphore(void); #endif /* HAVE_SYSTRAY */ gint aqualung_dialog_run(GtkDialog * dialog); guint aqualung_idle_add(GSourceFunc function, gpointer data); guint aqualung_timeout_add(guint interval, GSourceFunc function, gpointer data); void aqualung_tooltips_init(void); void aqualung_tooltips_set_enabled(gboolean enabled); #ifdef HAVE_SYSTRAY void aqualung_status_icon_set_tooltip_text(GtkStatusIcon * icon, const gchar * text); #endif /* HAVE_SYSTRAY */ void aqualung_widget_set_tooltip_text(GtkWidget * widget, const gchar * text); GtkWidget* gui_stock_label_button(gchar *label, const gchar *stock); GSList * file_chooser(char * title, GtkWidget * parent, GtkFileChooserAction action, int filter, gint multiple, char * destpath); void file_chooser_with_entry(char * title, GtkWidget * parent, GtkFileChooserAction action, int filter, GtkWidget * entry, char * destpath); int message_dialog(char * title, GtkWidget * parent, GtkMessageType type, GtkButtonsType buttons, GtkWidget * extra, char * text, ...); void insert_label_entry(GtkWidget * table, char * ltext, GtkWidget ** entry, char * etext, int y1, int y2, gboolean editable); void insert_label_entry_browse(GtkWidget * table, char * ltext, GtkWidget ** entry, char * etext, int y1, int y2, void (* browse_cb)(GtkButton * button, gpointer data)); void insert_label_entry_button(GtkWidget * table, char * ltext, GtkWidget ** entry, char * etext, GtkWidget * button, int y1, int y2); void insert_label_progbar_button(GtkWidget * table, char * ltext, GtkWidget ** progbar, GtkWidget * button, int y1, int y2); void insert_label_spin(GtkWidget * table, char * ltext, GtkWidget ** spin, int spinval, int y1, int y2); void insert_label_spin_with_limits(GtkWidget * table, char * ltext, GtkWidget ** spin, double spinval, double min, double max, int y1, int y2); void set_option_from_toggle(GtkWidget * widget, int * opt); void set_option_from_combo(GtkWidget * widget, int * opt); void set_option_from_spin(GtkWidget * widget, int * opt); void set_option_from_entry(GtkWidget * widget, char * opt, int n); void set_option_bit_from_toggle(GtkWidget * toggle, int * opt, int bit); #endif /* _UTILS_GUI_H */ // vim: shiftwidth=8:tabstop=8:softtabstop=8: aqualung-0.9beta11/src/version.h0000644000175000001440000000004211331334312013525 00000000000000#define AQUALUNG_VERSION "R-1114" aqualung-0.9beta11/src/volume.c0000644000175000001440000003720511002132477013360 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: volume.c 1009 2008-03-02 11:22:29Z tszilagyi $ */ #include #include #include #include #include #include #ifdef _WIN32 #include #else #include #endif /* _WIN32 */ #include "common.h" #include "utils_gui.h" #include "core.h" #include "decoder/file_decoder.h" #include "options.h" #include "music_browser.h" #include "store_file.h" #include "playlist.h" #include "i18n.h" #include "volume.h" #define EPSILON 0.00000000001 extern options_t options; extern GtkTreeStore * music_store; extern GtkWidget * main_window; GtkWidget * vol_window; int vol_slot_count; void voladj2str(float voladj, char * str) { if (fabs(voladj) < 0.05f) { sprintf(str, " %.1f dB", 0.0f); } else { sprintf(str, "% .1f dB", voladj); } } volume_t * volume_new(GtkTreeStore * store, int type) { volume_t * vol = NULL; if ((vol = (volume_t *)calloc(1, sizeof(volume_t))) == NULL) { fprintf(stderr, "volume_new(): calloc error\n"); return NULL; } vol->store = store; vol->type = type; AQUALUNG_COND_INIT(vol->thread_wait); #ifdef _WIN32 vol->thread_mutex = g_mutex_new(); vol->wait_mutex = g_mutex_new(); vol->thread_wait = g_cond_new(); #endif return vol; } void volume_push(volume_t * vol, char * file, GtkTreeIter iter) { vol_item_t * item = NULL; if ((item = (vol_item_t *)calloc(1, sizeof(vol_item_t))) == NULL) { fprintf(stderr, "volume_push(): calloc error\n"); return; } item->file = strdup(file); item->iter = iter; vol->queue = g_list_append(vol->queue, item); } void vol_item_free(vol_item_t * item) { free(item->file); free(item); } void volume_free(volume_t * vol) { #ifdef _WIN32 g_mutex_free(vol->thread_mutex); g_mutex_free(vol->wait_mutex); g_cond_free(vol->thread_wait); #endif if (vol->volumes != NULL) { free(vol->volumes); } g_list_free(vol->queue); free(vol); } inline static float rms_env_process(rms_env_t * r, const float x) { r->sum -= r->buffer[r->pos]; r->sum += x; r->buffer[r->pos] = x; r->pos++; if (r->pos == RMSSIZE) { r->pos = 0; } return sqrt(r->sum / (float)RMSSIZE); } gboolean vol_window_event(GtkWidget * widget, GdkEvent * event, gpointer * data) { if (event->type == GDK_DELETE) { gtk_window_iconify(GTK_WINDOW(vol_window)); return TRUE; } return FALSE; } gboolean volume_finalize(gpointer data) { volume_t * vol = (volume_t *)data; gtk_window_resize(GTK_WINDOW(vol_window), vol_window->allocation.width, vol_window->allocation.height - vol->slot->allocation.height); gtk_widget_destroy(vol->slot); vol->slot = NULL; g_source_remove(vol->update_tag); volume_free(vol); --vol_slot_count; if (vol_slot_count == 0) { unregister_toplevel_window(vol_window); gtk_widget_destroy(vol_window); vol_window = NULL; } return FALSE; } void vol_pause_event(GtkButton * button, gpointer data) { volume_t * vol = (volume_t *)data; vol->paused = !vol->paused; if (vol->paused) { gtk_button_set_label(button, _("Resume")); } else { gtk_button_set_label(button, _("Pause")); } } void vol_cancel_event(GtkButton * button, gpointer data) { volume_t * vol = (volume_t *)data; vol->cancelled = 1; } gboolean vol_set_filename_text(gpointer data) { volume_t * vol = (volume_t *)data; AQUALUNG_MUTEX_LOCK(vol->wait_mutex); if (vol->slot) { char * utf8; AQUALUNG_MUTEX_LOCK(vol->thread_mutex); utf8 = g_filename_display_name(vol->item->file); AQUALUNG_MUTEX_UNLOCK(vol->thread_mutex); gtk_entry_set_text(GTK_ENTRY(vol->file_entry), utf8); gtk_editable_set_position(GTK_EDITABLE(vol->file_entry), -1); g_free(utf8); } AQUALUNG_COND_SIGNAL(vol->thread_wait); AQUALUNG_MUTEX_UNLOCK(vol->wait_mutex); return FALSE; } gboolean vol_update_progress(gpointer data) { volume_t * vol = (volume_t *)data; if (vol->slot) { float fraction = 0.0f; char str_progress[10]; AQUALUNG_MUTEX_LOCK(vol->thread_mutex); if (vol->n_chunks != 0) { fraction = (float)vol->chunks_read / vol->n_chunks; } AQUALUNG_MUTEX_UNLOCK(vol->thread_mutex); if (fraction < 0 || fraction > 1.0f) { fraction = 0.0f; } gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(vol->progress), fraction); snprintf(str_progress, 10, "%.0f%%", fraction * 100.0f); gtk_progress_bar_set_text(GTK_PROGRESS_BAR(vol->progress), str_progress); } return TRUE; } void vol_store_voladj(GtkTreeStore * store, GtkTreeIter * iter, float voladj) { if (!gtk_tree_store_iter_is_valid(store, iter)) { return; } if (store == music_store) { /* music store */ track_data_t * data; gtk_tree_model_get(GTK_TREE_MODEL(music_store), iter, MS_COL_DATA, &data, -1); data->volume = voladj; music_store_mark_changed(iter); } else { /* playlist */ playlist_data_t * data; char str[32]; voladj2str(voladj, str); gtk_tree_model_get(GTK_TREE_MODEL(store), iter, PL_COL_DATA, &data, -1); data->voladj = voladj; gtk_tree_store_set(store, iter, PL_COL_VADJ, str, -1); } } gboolean vol_store_result_sep(gpointer data) { volume_t * vol = (volume_t *)data; AQUALUNG_MUTEX_LOCK(vol->wait_mutex); vol_store_voladj(vol->store, &vol->item->iter, (vol->store == music_store) ? vol->result : rva_from_volume(vol->result)); AQUALUNG_COND_SIGNAL(vol->thread_wait); AQUALUNG_MUTEX_UNLOCK(vol->wait_mutex); return FALSE; } gboolean vol_store_result_avg(gpointer data) { volume_t * vol = (volume_t *)data; GList * node = NULL; float voladj; AQUALUNG_MUTEX_LOCK(vol->wait_mutex); voladj = rva_from_multiple_volumes(vol->n_volumes, vol->volumes); for (node = vol->queue; node; node = node->next) { vol_item_t * item = (vol_item_t *)node->data; vol_store_voladj(vol->store, &item->iter, voladj); } AQUALUNG_COND_SIGNAL(vol->thread_wait); AQUALUNG_MUTEX_UNLOCK(vol->wait_mutex); return FALSE; } void create_volume_window() { GtkWidget * vbox; vol_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); register_toplevel_window(vol_window, TOP_WIN_SKIN | TOP_WIN_TRAY); gtk_window_set_transient_for(GTK_WINDOW(vol_window), GTK_WINDOW(main_window)); gtk_window_set_title(GTK_WINDOW(vol_window), _("Calculating volume level")); gtk_window_set_position(GTK_WINDOW(vol_window), GTK_WIN_POS_CENTER); gtk_window_resize(GTK_WINDOW(vol_window), 480, 110); g_signal_connect(G_OBJECT(vol_window), "event", G_CALLBACK(vol_window_event), NULL); gtk_container_set_border_width(GTK_CONTAINER(vol_window), 5); vbox = gtk_vbox_new(FALSE, 0); gtk_container_add(GTK_CONTAINER(vol_window), vbox); gtk_widget_show_all(vol_window); } void vol_create_gui(volume_t * vol) { GtkWidget * label; GtkWidget * vbox; GtkWidget * hbox; ++vol_slot_count; if (vol_window == NULL) { create_volume_window(); } vbox = gtk_bin_get_child(GTK_BIN(vol_window)); vol->slot = gtk_table_new(4, 3, FALSE); gtk_box_pack_start(GTK_BOX(vbox), vol->slot, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(vol->slot), gtk_hseparator_new(), 0, 3, 0, 1, GTK_FILL, GTK_FILL, 5, 5); hbox = gtk_hbox_new(FALSE, 0); label = gtk_label_new(_("File:")); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(vol->slot), hbox, 0, 1, 1, 2, GTK_FILL, GTK_FILL, 5, 5); vol->file_entry = gtk_entry_new(); gtk_editable_set_editable(GTK_EDITABLE(vol->file_entry), FALSE); gtk_table_attach(GTK_TABLE(vol->slot), vol->file_entry, 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, GTK_FILL, 5, 5); vol->pause_button = gtk_button_new_with_label(_("Pause")); g_signal_connect(vol->pause_button, "clicked", G_CALLBACK(vol_pause_event), vol); gtk_table_attach(GTK_TABLE(vol->slot), vol->pause_button, 2, 3, 1, 2, GTK_FILL, GTK_FILL, 5, 5); hbox = gtk_hbox_new(FALSE, 0); label = gtk_label_new(_("Progress:")); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(vol->slot), hbox, 0, 1, 2, 3, GTK_FILL, GTK_FILL, 5, 5); vol->progress = gtk_progress_bar_new(); gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(vol->progress), 0.0f); gtk_progress_bar_set_text(GTK_PROGRESS_BAR(vol->progress), "0.0%"); gtk_table_attach(GTK_TABLE(vol->slot), vol->progress, 1, 2, 2, 3, GTK_EXPAND | GTK_FILL, GTK_FILL, 5, 5); vol->cancel_button = gui_stock_label_button (_("Abort"), GTK_STOCK_CANCEL); g_signal_connect(vol->cancel_button, "clicked", G_CALLBACK(vol_cancel_event), vol); gtk_table_attach(GTK_TABLE(vol->slot), vol->cancel_button, 2, 3, 2, 3, GTK_FILL, GTK_FILL, 5, 5); gtk_table_attach(GTK_TABLE(vol->slot), gtk_hseparator_new(), 0, 3, 3, 4, GTK_FILL, GTK_FILL, 5, 5); gtk_widget_show_all(vol->slot); } /* if returns 1, file will be skipped */ int process_volume_setup(volume_t * vol) { if ((vol->fdec = file_decoder_new()) == NULL) { fprintf(stderr, "calculate_volume: error: file_decoder_new() returned NULL\n"); return 1; } if (file_decoder_open(vol->fdec, vol->item->file)) { fprintf(stderr, "file_decoder_open() failed on %s\n", vol->item->file); return 1; } if ((vol->rms = (rms_env_t *)calloc(1, sizeof(rms_env_t))) == NULL) { fprintf(stderr, "calculate_volume(): calloc error\n"); return 1; } vol->chunks_read = 0; vol->chunk_size = vol->fdec->fileinfo.sample_rate / 100; vol->n_chunks = vol->fdec->fileinfo.total_samples / vol->chunk_size + 1; AQUALUNG_MUTEX_LOCK(vol->wait_mutex); aqualung_idle_add(vol_set_filename_text, vol); AQUALUNG_COND_WAIT(vol->thread_wait, vol->wait_mutex); AQUALUNG_MUTEX_UNLOCK(vol->wait_mutex); vol->result = 0.0f; return 0; } void * volume_thread(void * arg) { volume_t * vol = (volume_t *)arg; GList * node; float * samples = NULL; unsigned long numread; float chunk_power = 0.0f; float rms; unsigned long i; struct timespec req_time; struct timespec rem_time; req_time.tv_sec = 0; req_time.tv_nsec = 500000000; AQUALUNG_THREAD_DETACH(); for (node = vol->queue; node; node = node->next) { vol->item = (vol_item_t *)node->data; if (process_volume_setup(vol)) { continue; } if ((samples = (float *)malloc(vol->chunk_size * vol->fdec->fileinfo.channels * sizeof(float))) == NULL) { fprintf(stderr, "volume_thread(): malloc() error\n"); file_decoder_close(vol->fdec); file_decoder_delete(vol->fdec); free(vol->rms); break; } do { numread = file_decoder_read(vol->fdec, samples, vol->chunk_size); vol->chunks_read++; /* calculate signal power of chunk and feed it in the rms envelope */ if (numread > 0) { for (i = 0; i < numread * vol->fdec->fileinfo.channels; i++) { chunk_power += samples[i] * samples[i]; } chunk_power /= numread * vol->fdec->fileinfo.channels; rms = rms_env_process(vol->rms, chunk_power); if (rms > vol->result) { vol->result = rms; } } while (vol->paused && !vol->cancelled) { nanosleep(&req_time, &rem_time); } } while (numread == vol->chunk_size && !vol->cancelled); if (!vol->cancelled) { vol->result = 20.0f * log10f(vol->result); #ifdef HAVE_MPEG /* compensate for anti-clip vol.reduction in dec_mpeg.c/mpeg_output() */ if (vol->fdec->file_lib == MAD_LIB) { vol->result += 1.8f; } #endif /* HAVE_MPEG */ if (vol->type == VOLUME_SEPARATE) { AQUALUNG_MUTEX_LOCK(vol->wait_mutex); aqualung_idle_add(vol_store_result_sep, vol); AQUALUNG_COND_WAIT(vol->thread_wait, vol->wait_mutex); AQUALUNG_MUTEX_UNLOCK(vol->wait_mutex); } else if (vol->type == VOLUME_AVERAGE) { vol->n_volumes++; if ((vol->volumes = realloc(vol->volumes, vol->n_volumes * sizeof(float))) == NULL) { fprintf(stderr, "volume_thread(): realloc error\n"); return NULL; } vol->volumes[vol->n_volumes - 1] = vol->result; } } file_decoder_close(vol->fdec); file_decoder_delete(vol->fdec); free(vol->rms); free(samples); if (vol->cancelled) { break; } } if (!vol->cancelled && vol->type == VOLUME_AVERAGE) { AQUALUNG_MUTEX_LOCK(vol->wait_mutex); aqualung_idle_add(vol_store_result_avg, vol); AQUALUNG_COND_WAIT(vol->thread_wait, vol->wait_mutex); AQUALUNG_MUTEX_UNLOCK(vol->wait_mutex); } for (node = vol->queue; node; node = node->next) { vol_item_free((vol_item_t *)node->data); } aqualung_idle_add(volume_finalize, vol); return NULL; } void volume_start(volume_t * vol) { if (vol->queue == NULL) { return; } vol_create_gui(vol); AQUALUNG_THREAD_CREATE(vol->thread_id, NULL, volume_thread, vol); vol->update_tag = aqualung_timeout_add(250, vol_update_progress, vol); } float rva_from_volume(float volume) { return ((volume - options.rva_refvol) * (options.rva_steepness - 1.0f)); } /* Replaygain is almost always the "89 dB SPL" type. * This means a -14 dBFS pink noise reference signal is used. * A positive replaygain value means it's quiter than the reference signal. * The magic values are due to different ways of calculating the levels. * They're only approximations though. */ #define RG_REFERENCE_LEVEL -14.0 #define RG_MAGIC_VAL1 -2.1 /* emperical */ #define RG_MAGIC_VAL2 1.05 /* emperical */ #define RG_TO_VOLUME(replaygain) ((-replaygain + RG_REFERENCE_LEVEL + RG_MAGIC_VAL1) * RG_MAGIC_VAL2) float rva_from_replaygain(float rg) { return rva_from_volume(RG_TO_VOLUME(rg)); } float rva_from_multiple_volumes(int nlevels, float * volumes) { int i, files_to_avg; char * badlevels; double sum, level, mean_level, variance, std_dev; double level_difference, threshold; if ((badlevels = (char *)calloc(nlevels, sizeof(char))) == NULL) { fprintf(stderr, "rva_from_multiple_volumes() : calloc error\n"); return 0.0f; } sum = 0.0; for (i = 0; i < nlevels; i++) { sum += db2lin(volumes[i]); } mean_level = sum / nlevels; if (!options.rva_use_linear_thresh) { /* use stddev_thresh */ sum = 0; for (i = 0; i < nlevels; i++) { double tmp = 20.0 * log10(db2lin(volumes[i]) / mean_level); sum += tmp * tmp; } variance = sum / nlevels; /* get standard deviation */ if (variance < EPSILON) { std_dev = 0.0; } else { std_dev = sqrt(variance); } threshold = options.rva_avg_stddev_thresh * std_dev; } else { threshold = options.rva_avg_linear_thresh; } if (threshold > EPSILON && nlevels > 1) { for (i = 0; i < nlevels; i++) { level_difference = fabs(20.0 * log10(mean_level / db2lin(volumes[i]))); if (level_difference > threshold) { badlevels[i] = 1; } } } /* throw out the levels marked as bad */ files_to_avg = 0; sum = 0; for (i = 0; i < nlevels; i++) { if (!badlevels[i]) { sum += db2lin(volumes[i]); files_to_avg++; } } free(badlevels); if (files_to_avg == 0) { fprintf(stderr, "rva_from_multiple_volumes: all files ignored, using mean value.\n"); return rva_from_volume(20 * log10(mean_level)); } level = sum / files_to_avg; return rva_from_volume(20 * log10(level)); } // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/volume.h0000644000175000001440000000441611105650335013365 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: volume.h 1033 2008-11-08 14:31:56Z tszilagyi $ */ #ifndef _VOLUME_H #define _VOLUME_H #include #include "common.h" #ifdef _WIN32 #include #else #include #endif /* _WIN32 */ #define RMSSIZE 100 #define VOLUME_SEPARATE 0 #define VOLUME_AVERAGE 1 typedef struct { float buffer[RMSSIZE]; unsigned int pos; float sum; } rms_env_t; typedef struct { GtkTreeIter iter; char * file; } vol_item_t; typedef struct { GtkTreeStore * store; GList * queue; int update_tag; int cancelled; int paused; int window_visible; int type; AQUALUNG_THREAD_DECLARE(thread_id); AQUALUNG_MUTEX_DECLARE(thread_mutex); AQUALUNG_MUTEX_DECLARE(wait_mutex); AQUALUNG_COND_DECLARE(thread_wait); GtkWidget * slot; GtkWidget * progress; GtkWidget * pause_button; GtkWidget * cancel_button; GtkWidget * file_entry; vol_item_t * item; file_decoder_t * fdec; unsigned long chunk_size; unsigned long n_chunks; unsigned long chunks_read; float result; rms_env_t * rms; float * volumes; unsigned int n_volumes; } volume_t; volume_t * volume_new(GtkTreeStore * store, int type); void volume_push(volume_t * vol, char * file, GtkTreeIter iter); void volume_start(volume_t * vol); void voladj2str(float voladj, char * str); float rva_from_volume(float volume); float rva_from_replaygain(float rg); float rva_from_multiple_volumes(int nlevels, float * volumes); #endif /* _VOLUME_H */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/decoder/0000777000175000001440000000000011331334363013372 500000000000000aqualung-0.9beta11/src/decoder/Makefile.am0000644000175000001440000000071011253161434015340 00000000000000noinst_LIBRARIES = libdecoder.a libdecoder_a_CFLAGS = $(LIBAVCODEC_CFLAGS) $(LIBAVFORMAT_CFLAGS) libdecoder_a_SOURCES = \ dec_cdda.h dec_cdda.c \ dec_flac.h dec_flac.c \ dec_lavc.h dec_lavc.c \ dec_mac.h dec_mac.cpp \ dec_mod.h dec_mod.c \ dec_mpc.h dec_mpc.c \ dec_mpeg.h dec_mpeg.c \ dec_null.h dec_null.c \ dec_sndfile.h dec_sndfile.c \ dec_speex.h dec_speex.c \ dec_vorbis.h dec_vorbis.c \ dec_wavpack.h dec_wavpack.c \ file_decoder.h file_decoder.c aqualung-0.9beta11/src/decoder/Makefile.in0000644000175000001440000010762211331334253015361 00000000000000# Makefile.in generated by automake 1.10.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # This Makefile.in 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. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = src/decoder DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = LIBRARIES = $(noinst_LIBRARIES) AR = ar ARFLAGS = cru libdecoder_a_AR = $(AR) $(ARFLAGS) libdecoder_a_LIBADD = am_libdecoder_a_OBJECTS = libdecoder_a-dec_cdda.$(OBJEXT) \ libdecoder_a-dec_flac.$(OBJEXT) \ libdecoder_a-dec_lavc.$(OBJEXT) dec_mac.$(OBJEXT) \ libdecoder_a-dec_mod.$(OBJEXT) libdecoder_a-dec_mpc.$(OBJEXT) \ libdecoder_a-dec_mpeg.$(OBJEXT) \ libdecoder_a-dec_null.$(OBJEXT) \ libdecoder_a-dec_sndfile.$(OBJEXT) \ libdecoder_a-dec_speex.$(OBJEXT) \ libdecoder_a-dec_vorbis.$(OBJEXT) \ libdecoder_a-dec_wavpack.$(OBJEXT) \ libdecoder_a-file_decoder.$(OBJEXT) libdecoder_a_OBJECTS = $(am_libdecoder_a_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ SOURCES = $(libdecoder_a_SOURCES) DIST_SOURCES = $(libdecoder_a_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBAVCODEC_CFLAGS = @LIBAVCODEC_CFLAGS@ LIBAVCODEC_LIBS = @LIBAVCODEC_LIBS@ LIBAVFORMAT_CFLAGS = @LIBAVFORMAT_CFLAGS@ LIBAVFORMAT_LIBS = @LIBAVFORMAT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ var = @var@ noinst_LIBRARIES = libdecoder.a libdecoder_a_CFLAGS = $(LIBAVCODEC_CFLAGS) $(LIBAVFORMAT_CFLAGS) libdecoder_a_SOURCES = \ dec_cdda.h dec_cdda.c \ dec_flac.h dec_flac.c \ dec_lavc.h dec_lavc.c \ dec_mac.h dec_mac.cpp \ dec_mod.h dec_mod.c \ dec_mpc.h dec_mpc.c \ dec_mpeg.h dec_mpeg.c \ dec_null.h dec_null.c \ dec_sndfile.h dec_sndfile.c \ dec_speex.h dec_speex.c \ dec_vorbis.h dec_vorbis.c \ dec_wavpack.h dec_wavpack.c \ file_decoder.h file_decoder.c all: all-am .SUFFIXES: .SUFFIXES: .c .cpp .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/decoder/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/decoder/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) libdecoder.a: $(libdecoder_a_OBJECTS) $(libdecoder_a_DEPENDENCIES) -rm -f libdecoder.a $(libdecoder_a_AR) libdecoder.a $(libdecoder_a_OBJECTS) $(libdecoder_a_LIBADD) $(RANLIB) libdecoder.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dec_mac.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdecoder_a-dec_cdda.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdecoder_a-dec_flac.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdecoder_a-dec_lavc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdecoder_a-dec_mod.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdecoder_a-dec_mpc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdecoder_a-dec_mpeg.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdecoder_a-dec_null.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdecoder_a-dec_sndfile.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdecoder_a-dec_speex.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdecoder_a-dec_vorbis.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdecoder_a-dec_wavpack.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdecoder_a-file_decoder.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` libdecoder_a-dec_cdda.o: dec_cdda.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdecoder_a_CFLAGS) $(CFLAGS) -MT libdecoder_a-dec_cdda.o -MD -MP -MF $(DEPDIR)/libdecoder_a-dec_cdda.Tpo -c -o libdecoder_a-dec_cdda.o `test -f 'dec_cdda.c' || echo '$(srcdir)/'`dec_cdda.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libdecoder_a-dec_cdda.Tpo $(DEPDIR)/libdecoder_a-dec_cdda.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dec_cdda.c' object='libdecoder_a-dec_cdda.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdecoder_a_CFLAGS) $(CFLAGS) -c -o libdecoder_a-dec_cdda.o `test -f 'dec_cdda.c' || echo '$(srcdir)/'`dec_cdda.c libdecoder_a-dec_cdda.obj: dec_cdda.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdecoder_a_CFLAGS) $(CFLAGS) -MT libdecoder_a-dec_cdda.obj -MD -MP -MF $(DEPDIR)/libdecoder_a-dec_cdda.Tpo -c -o libdecoder_a-dec_cdda.obj `if test -f 'dec_cdda.c'; then $(CYGPATH_W) 'dec_cdda.c'; else $(CYGPATH_W) '$(srcdir)/dec_cdda.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libdecoder_a-dec_cdda.Tpo $(DEPDIR)/libdecoder_a-dec_cdda.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dec_cdda.c' object='libdecoder_a-dec_cdda.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdecoder_a_CFLAGS) $(CFLAGS) -c -o libdecoder_a-dec_cdda.obj `if test -f 'dec_cdda.c'; then $(CYGPATH_W) 'dec_cdda.c'; else $(CYGPATH_W) '$(srcdir)/dec_cdda.c'; fi` libdecoder_a-dec_flac.o: dec_flac.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdecoder_a_CFLAGS) $(CFLAGS) -MT libdecoder_a-dec_flac.o -MD -MP -MF $(DEPDIR)/libdecoder_a-dec_flac.Tpo -c -o libdecoder_a-dec_flac.o `test -f 'dec_flac.c' || echo '$(srcdir)/'`dec_flac.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libdecoder_a-dec_flac.Tpo $(DEPDIR)/libdecoder_a-dec_flac.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dec_flac.c' object='libdecoder_a-dec_flac.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdecoder_a_CFLAGS) $(CFLAGS) -c -o libdecoder_a-dec_flac.o `test -f 'dec_flac.c' || echo '$(srcdir)/'`dec_flac.c libdecoder_a-dec_flac.obj: dec_flac.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdecoder_a_CFLAGS) $(CFLAGS) -MT libdecoder_a-dec_flac.obj -MD -MP -MF $(DEPDIR)/libdecoder_a-dec_flac.Tpo -c -o libdecoder_a-dec_flac.obj `if test -f 'dec_flac.c'; then $(CYGPATH_W) 'dec_flac.c'; else $(CYGPATH_W) '$(srcdir)/dec_flac.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libdecoder_a-dec_flac.Tpo $(DEPDIR)/libdecoder_a-dec_flac.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dec_flac.c' object='libdecoder_a-dec_flac.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdecoder_a_CFLAGS) $(CFLAGS) -c -o libdecoder_a-dec_flac.obj `if test -f 'dec_flac.c'; then $(CYGPATH_W) 'dec_flac.c'; else $(CYGPATH_W) '$(srcdir)/dec_flac.c'; fi` libdecoder_a-dec_lavc.o: dec_lavc.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdecoder_a_CFLAGS) $(CFLAGS) -MT libdecoder_a-dec_lavc.o -MD -MP -MF $(DEPDIR)/libdecoder_a-dec_lavc.Tpo -c -o libdecoder_a-dec_lavc.o `test -f 'dec_lavc.c' || echo '$(srcdir)/'`dec_lavc.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libdecoder_a-dec_lavc.Tpo $(DEPDIR)/libdecoder_a-dec_lavc.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dec_lavc.c' object='libdecoder_a-dec_lavc.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdecoder_a_CFLAGS) $(CFLAGS) -c -o libdecoder_a-dec_lavc.o `test -f 'dec_lavc.c' || echo '$(srcdir)/'`dec_lavc.c libdecoder_a-dec_lavc.obj: dec_lavc.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdecoder_a_CFLAGS) $(CFLAGS) -MT libdecoder_a-dec_lavc.obj -MD -MP -MF $(DEPDIR)/libdecoder_a-dec_lavc.Tpo -c -o libdecoder_a-dec_lavc.obj `if test -f 'dec_lavc.c'; then $(CYGPATH_W) 'dec_lavc.c'; else $(CYGPATH_W) '$(srcdir)/dec_lavc.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libdecoder_a-dec_lavc.Tpo $(DEPDIR)/libdecoder_a-dec_lavc.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dec_lavc.c' object='libdecoder_a-dec_lavc.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdecoder_a_CFLAGS) $(CFLAGS) -c -o libdecoder_a-dec_lavc.obj `if test -f 'dec_lavc.c'; then $(CYGPATH_W) 'dec_lavc.c'; else $(CYGPATH_W) '$(srcdir)/dec_lavc.c'; fi` libdecoder_a-dec_mod.o: dec_mod.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdecoder_a_CFLAGS) $(CFLAGS) -MT libdecoder_a-dec_mod.o -MD -MP -MF $(DEPDIR)/libdecoder_a-dec_mod.Tpo -c -o libdecoder_a-dec_mod.o `test -f 'dec_mod.c' || echo '$(srcdir)/'`dec_mod.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libdecoder_a-dec_mod.Tpo $(DEPDIR)/libdecoder_a-dec_mod.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dec_mod.c' object='libdecoder_a-dec_mod.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdecoder_a_CFLAGS) $(CFLAGS) -c -o libdecoder_a-dec_mod.o `test -f 'dec_mod.c' || echo '$(srcdir)/'`dec_mod.c libdecoder_a-dec_mod.obj: dec_mod.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdecoder_a_CFLAGS) $(CFLAGS) -MT libdecoder_a-dec_mod.obj -MD -MP -MF $(DEPDIR)/libdecoder_a-dec_mod.Tpo -c -o libdecoder_a-dec_mod.obj `if test -f 'dec_mod.c'; then $(CYGPATH_W) 'dec_mod.c'; else $(CYGPATH_W) '$(srcdir)/dec_mod.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libdecoder_a-dec_mod.Tpo $(DEPDIR)/libdecoder_a-dec_mod.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dec_mod.c' object='libdecoder_a-dec_mod.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdecoder_a_CFLAGS) $(CFLAGS) -c -o libdecoder_a-dec_mod.obj `if test -f 'dec_mod.c'; then $(CYGPATH_W) 'dec_mod.c'; else $(CYGPATH_W) '$(srcdir)/dec_mod.c'; fi` libdecoder_a-dec_mpc.o: dec_mpc.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdecoder_a_CFLAGS) $(CFLAGS) -MT libdecoder_a-dec_mpc.o -MD -MP -MF $(DEPDIR)/libdecoder_a-dec_mpc.Tpo -c -o libdecoder_a-dec_mpc.o `test -f 'dec_mpc.c' || echo '$(srcdir)/'`dec_mpc.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libdecoder_a-dec_mpc.Tpo $(DEPDIR)/libdecoder_a-dec_mpc.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dec_mpc.c' object='libdecoder_a-dec_mpc.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdecoder_a_CFLAGS) $(CFLAGS) -c -o libdecoder_a-dec_mpc.o `test -f 'dec_mpc.c' || echo '$(srcdir)/'`dec_mpc.c libdecoder_a-dec_mpc.obj: dec_mpc.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdecoder_a_CFLAGS) $(CFLAGS) -MT libdecoder_a-dec_mpc.obj -MD -MP -MF $(DEPDIR)/libdecoder_a-dec_mpc.Tpo -c -o libdecoder_a-dec_mpc.obj `if test -f 'dec_mpc.c'; then $(CYGPATH_W) 'dec_mpc.c'; else $(CYGPATH_W) '$(srcdir)/dec_mpc.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libdecoder_a-dec_mpc.Tpo $(DEPDIR)/libdecoder_a-dec_mpc.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dec_mpc.c' object='libdecoder_a-dec_mpc.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdecoder_a_CFLAGS) $(CFLAGS) -c -o libdecoder_a-dec_mpc.obj `if test -f 'dec_mpc.c'; then $(CYGPATH_W) 'dec_mpc.c'; else $(CYGPATH_W) '$(srcdir)/dec_mpc.c'; fi` libdecoder_a-dec_mpeg.o: dec_mpeg.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdecoder_a_CFLAGS) $(CFLAGS) -MT libdecoder_a-dec_mpeg.o -MD -MP -MF $(DEPDIR)/libdecoder_a-dec_mpeg.Tpo -c -o libdecoder_a-dec_mpeg.o `test -f 'dec_mpeg.c' || echo '$(srcdir)/'`dec_mpeg.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libdecoder_a-dec_mpeg.Tpo $(DEPDIR)/libdecoder_a-dec_mpeg.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dec_mpeg.c' object='libdecoder_a-dec_mpeg.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdecoder_a_CFLAGS) $(CFLAGS) -c -o libdecoder_a-dec_mpeg.o `test -f 'dec_mpeg.c' || echo '$(srcdir)/'`dec_mpeg.c libdecoder_a-dec_mpeg.obj: dec_mpeg.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdecoder_a_CFLAGS) $(CFLAGS) -MT libdecoder_a-dec_mpeg.obj -MD -MP -MF $(DEPDIR)/libdecoder_a-dec_mpeg.Tpo -c -o libdecoder_a-dec_mpeg.obj `if test -f 'dec_mpeg.c'; then $(CYGPATH_W) 'dec_mpeg.c'; else $(CYGPATH_W) '$(srcdir)/dec_mpeg.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libdecoder_a-dec_mpeg.Tpo $(DEPDIR)/libdecoder_a-dec_mpeg.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dec_mpeg.c' object='libdecoder_a-dec_mpeg.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdecoder_a_CFLAGS) $(CFLAGS) -c -o libdecoder_a-dec_mpeg.obj `if test -f 'dec_mpeg.c'; then $(CYGPATH_W) 'dec_mpeg.c'; else $(CYGPATH_W) '$(srcdir)/dec_mpeg.c'; fi` libdecoder_a-dec_null.o: dec_null.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdecoder_a_CFLAGS) $(CFLAGS) -MT libdecoder_a-dec_null.o -MD -MP -MF $(DEPDIR)/libdecoder_a-dec_null.Tpo -c -o libdecoder_a-dec_null.o `test -f 'dec_null.c' || echo '$(srcdir)/'`dec_null.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libdecoder_a-dec_null.Tpo $(DEPDIR)/libdecoder_a-dec_null.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dec_null.c' object='libdecoder_a-dec_null.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdecoder_a_CFLAGS) $(CFLAGS) -c -o libdecoder_a-dec_null.o `test -f 'dec_null.c' || echo '$(srcdir)/'`dec_null.c libdecoder_a-dec_null.obj: dec_null.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdecoder_a_CFLAGS) $(CFLAGS) -MT libdecoder_a-dec_null.obj -MD -MP -MF $(DEPDIR)/libdecoder_a-dec_null.Tpo -c -o libdecoder_a-dec_null.obj `if test -f 'dec_null.c'; then $(CYGPATH_W) 'dec_null.c'; else $(CYGPATH_W) '$(srcdir)/dec_null.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libdecoder_a-dec_null.Tpo $(DEPDIR)/libdecoder_a-dec_null.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dec_null.c' object='libdecoder_a-dec_null.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdecoder_a_CFLAGS) $(CFLAGS) -c -o libdecoder_a-dec_null.obj `if test -f 'dec_null.c'; then $(CYGPATH_W) 'dec_null.c'; else $(CYGPATH_W) '$(srcdir)/dec_null.c'; fi` libdecoder_a-dec_sndfile.o: dec_sndfile.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdecoder_a_CFLAGS) $(CFLAGS) -MT libdecoder_a-dec_sndfile.o -MD -MP -MF $(DEPDIR)/libdecoder_a-dec_sndfile.Tpo -c -o libdecoder_a-dec_sndfile.o `test -f 'dec_sndfile.c' || echo '$(srcdir)/'`dec_sndfile.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libdecoder_a-dec_sndfile.Tpo $(DEPDIR)/libdecoder_a-dec_sndfile.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dec_sndfile.c' object='libdecoder_a-dec_sndfile.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdecoder_a_CFLAGS) $(CFLAGS) -c -o libdecoder_a-dec_sndfile.o `test -f 'dec_sndfile.c' || echo '$(srcdir)/'`dec_sndfile.c libdecoder_a-dec_sndfile.obj: dec_sndfile.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdecoder_a_CFLAGS) $(CFLAGS) -MT libdecoder_a-dec_sndfile.obj -MD -MP -MF $(DEPDIR)/libdecoder_a-dec_sndfile.Tpo -c -o libdecoder_a-dec_sndfile.obj `if test -f 'dec_sndfile.c'; then $(CYGPATH_W) 'dec_sndfile.c'; else $(CYGPATH_W) '$(srcdir)/dec_sndfile.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libdecoder_a-dec_sndfile.Tpo $(DEPDIR)/libdecoder_a-dec_sndfile.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dec_sndfile.c' object='libdecoder_a-dec_sndfile.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdecoder_a_CFLAGS) $(CFLAGS) -c -o libdecoder_a-dec_sndfile.obj `if test -f 'dec_sndfile.c'; then $(CYGPATH_W) 'dec_sndfile.c'; else $(CYGPATH_W) '$(srcdir)/dec_sndfile.c'; fi` libdecoder_a-dec_speex.o: dec_speex.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdecoder_a_CFLAGS) $(CFLAGS) -MT libdecoder_a-dec_speex.o -MD -MP -MF $(DEPDIR)/libdecoder_a-dec_speex.Tpo -c -o libdecoder_a-dec_speex.o `test -f 'dec_speex.c' || echo '$(srcdir)/'`dec_speex.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libdecoder_a-dec_speex.Tpo $(DEPDIR)/libdecoder_a-dec_speex.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dec_speex.c' object='libdecoder_a-dec_speex.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdecoder_a_CFLAGS) $(CFLAGS) -c -o libdecoder_a-dec_speex.o `test -f 'dec_speex.c' || echo '$(srcdir)/'`dec_speex.c libdecoder_a-dec_speex.obj: dec_speex.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdecoder_a_CFLAGS) $(CFLAGS) -MT libdecoder_a-dec_speex.obj -MD -MP -MF $(DEPDIR)/libdecoder_a-dec_speex.Tpo -c -o libdecoder_a-dec_speex.obj `if test -f 'dec_speex.c'; then $(CYGPATH_W) 'dec_speex.c'; else $(CYGPATH_W) '$(srcdir)/dec_speex.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libdecoder_a-dec_speex.Tpo $(DEPDIR)/libdecoder_a-dec_speex.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dec_speex.c' object='libdecoder_a-dec_speex.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdecoder_a_CFLAGS) $(CFLAGS) -c -o libdecoder_a-dec_speex.obj `if test -f 'dec_speex.c'; then $(CYGPATH_W) 'dec_speex.c'; else $(CYGPATH_W) '$(srcdir)/dec_speex.c'; fi` libdecoder_a-dec_vorbis.o: dec_vorbis.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdecoder_a_CFLAGS) $(CFLAGS) -MT libdecoder_a-dec_vorbis.o -MD -MP -MF $(DEPDIR)/libdecoder_a-dec_vorbis.Tpo -c -o libdecoder_a-dec_vorbis.o `test -f 'dec_vorbis.c' || echo '$(srcdir)/'`dec_vorbis.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libdecoder_a-dec_vorbis.Tpo $(DEPDIR)/libdecoder_a-dec_vorbis.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dec_vorbis.c' object='libdecoder_a-dec_vorbis.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdecoder_a_CFLAGS) $(CFLAGS) -c -o libdecoder_a-dec_vorbis.o `test -f 'dec_vorbis.c' || echo '$(srcdir)/'`dec_vorbis.c libdecoder_a-dec_vorbis.obj: dec_vorbis.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdecoder_a_CFLAGS) $(CFLAGS) -MT libdecoder_a-dec_vorbis.obj -MD -MP -MF $(DEPDIR)/libdecoder_a-dec_vorbis.Tpo -c -o libdecoder_a-dec_vorbis.obj `if test -f 'dec_vorbis.c'; then $(CYGPATH_W) 'dec_vorbis.c'; else $(CYGPATH_W) '$(srcdir)/dec_vorbis.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libdecoder_a-dec_vorbis.Tpo $(DEPDIR)/libdecoder_a-dec_vorbis.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dec_vorbis.c' object='libdecoder_a-dec_vorbis.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdecoder_a_CFLAGS) $(CFLAGS) -c -o libdecoder_a-dec_vorbis.obj `if test -f 'dec_vorbis.c'; then $(CYGPATH_W) 'dec_vorbis.c'; else $(CYGPATH_W) '$(srcdir)/dec_vorbis.c'; fi` libdecoder_a-dec_wavpack.o: dec_wavpack.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdecoder_a_CFLAGS) $(CFLAGS) -MT libdecoder_a-dec_wavpack.o -MD -MP -MF $(DEPDIR)/libdecoder_a-dec_wavpack.Tpo -c -o libdecoder_a-dec_wavpack.o `test -f 'dec_wavpack.c' || echo '$(srcdir)/'`dec_wavpack.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libdecoder_a-dec_wavpack.Tpo $(DEPDIR)/libdecoder_a-dec_wavpack.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dec_wavpack.c' object='libdecoder_a-dec_wavpack.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdecoder_a_CFLAGS) $(CFLAGS) -c -o libdecoder_a-dec_wavpack.o `test -f 'dec_wavpack.c' || echo '$(srcdir)/'`dec_wavpack.c libdecoder_a-dec_wavpack.obj: dec_wavpack.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdecoder_a_CFLAGS) $(CFLAGS) -MT libdecoder_a-dec_wavpack.obj -MD -MP -MF $(DEPDIR)/libdecoder_a-dec_wavpack.Tpo -c -o libdecoder_a-dec_wavpack.obj `if test -f 'dec_wavpack.c'; then $(CYGPATH_W) 'dec_wavpack.c'; else $(CYGPATH_W) '$(srcdir)/dec_wavpack.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libdecoder_a-dec_wavpack.Tpo $(DEPDIR)/libdecoder_a-dec_wavpack.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dec_wavpack.c' object='libdecoder_a-dec_wavpack.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdecoder_a_CFLAGS) $(CFLAGS) -c -o libdecoder_a-dec_wavpack.obj `if test -f 'dec_wavpack.c'; then $(CYGPATH_W) 'dec_wavpack.c'; else $(CYGPATH_W) '$(srcdir)/dec_wavpack.c'; fi` libdecoder_a-file_decoder.o: file_decoder.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdecoder_a_CFLAGS) $(CFLAGS) -MT libdecoder_a-file_decoder.o -MD -MP -MF $(DEPDIR)/libdecoder_a-file_decoder.Tpo -c -o libdecoder_a-file_decoder.o `test -f 'file_decoder.c' || echo '$(srcdir)/'`file_decoder.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libdecoder_a-file_decoder.Tpo $(DEPDIR)/libdecoder_a-file_decoder.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='file_decoder.c' object='libdecoder_a-file_decoder.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdecoder_a_CFLAGS) $(CFLAGS) -c -o libdecoder_a-file_decoder.o `test -f 'file_decoder.c' || echo '$(srcdir)/'`file_decoder.c libdecoder_a-file_decoder.obj: file_decoder.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdecoder_a_CFLAGS) $(CFLAGS) -MT libdecoder_a-file_decoder.obj -MD -MP -MF $(DEPDIR)/libdecoder_a-file_decoder.Tpo -c -o libdecoder_a-file_decoder.obj `if test -f 'file_decoder.c'; then $(CYGPATH_W) 'file_decoder.c'; else $(CYGPATH_W) '$(srcdir)/file_decoder.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libdecoder_a-file_decoder.Tpo $(DEPDIR)/libdecoder_a-file_decoder.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='file_decoder.c' object='libdecoder_a-file_decoder.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdecoder_a_CFLAGS) $(CFLAGS) -c -o libdecoder_a-file_decoder.obj `if test -f 'file_decoder.c'; then $(CYGPATH_W) 'file_decoder.c'; else $(CYGPATH_W) '$(srcdir)/file_decoder.c'; fi` .cpp.o: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-exec-am: install-html: install-html-am install-info: install-info-am install-man: install-pdf: install-pdf-am install-ps: install-ps-am installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-noinstLIBRARIES ctags distclean distclean-compile \ distclean-generic distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: aqualung-0.9beta11/src/decoder/dec_cdda.h0000644000175000001440000000513611243310677015176 00000000000000/* -*- linux-c -*- Copyright (C) 2005 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: dec_cdda.h 1068 2009-07-24 12:02:30Z peterszilagyi $ */ #ifndef _DEC_CDDA_H #define _DEC_CDDA_H #ifdef HAVE_CDDA #ifdef HAVE_CDDB #define _TMP_HAVE_CDDB 1 #undef HAVE_CDDB #endif /* HAVE_CDDB */ #include #include #include #ifdef HAVE_CDDB #undef HAVE_CDDB #endif /* HAVE_CDDB */ #ifdef _TMP_HAVE_CDDB #define HAVE_CDDB 1 #undef _TMP_HAVE_CDDB #endif /* _TMP_HAVE_CDDB */ #ifdef _WIN32 #include #else #include #endif /* _WIN32*/ #include "../cdda.h" #endif /* HAVE_CDDA */ #include "file_decoder.h" #ifdef HAVE_CDDA /* size of ringbuffer for decoded CD Audio data (in frames) */ #define RB_CDDA_SIZE (1<<20) typedef struct _cdda_pdata_t { rb_t * rb; char device_path[CDDA_MAXLEN]; track_t track_no; CdIo_t * cdio; cdrom_drive_t * drive; cdrom_paranoia_t * paranoia; lsn_t first_lsn; lsn_t last_lsn; lsn_t disc_last_lsn; int overread_sectors; lsn_t pos_lsn; int is_eos; AQUALUNG_THREAD_DECLARE(cdda_reader_id) AQUALUNG_MUTEX_DECLARE(cdda_reader_mutex) int cdda_reader_status; int paranoia_mode; int paranoia_maxretries; } cdda_pdata_t; #endif /* HAVE_CDDA */ decoder_t * cdda_decoder_init(file_decoder_t * fdec); #ifdef HAVE_CDDA void cdda_decoder_destroy(decoder_t * dec); int cdda_decoder_open(decoder_t * dec, char * filename); void cdda_decoder_send_metadata(decoder_t * dec); int cdda_decoder_reopen(decoder_t * dec, char * filename); void cdda_decoder_set_mode(decoder_t * dec, int drive_speed, int paranoia_mode, int paranoia_maxretries); void cdda_decoder_close(decoder_t * dec); unsigned int cdda_decoder_read(decoder_t * dec, float * dest, int num); void cdda_decoder_seek(decoder_t * dec, unsigned long long seek_to_pos); #endif /* HAVE_CDDA */ #endif /* _DEC_CDDA_H */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/decoder/dec_cdda.c0000644000175000001440000003371611243310677015176 00000000000000/* -*- linux-c -*- Copyright (C) 2005 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: dec_cdda.c 1068 2009-07-24 12:02:30Z peterszilagyi $ */ #include #include #include #include #include #include "../i18n.h" #include "../cdda.h" #include "../utils.h" #include "dec_cdda.h" #ifdef HAVE_CDDA extern size_t sample_size; #define CDDA_READER_FREE 0 #define CDDA_READER_BUSY 1 int cdda_read_error[CDDA_DRIVES_MAX]; /* This mess is mandated by the error callback of cdio_paranoia_read * not having a context argument. We have to use a different callback * for each possible decoder, with the context hard-coded. ARGH! */ #define DEFINE_ERROR_CB(n) \ void \ cdda_paranoia_callback_##n(long int inpos, paranoia_cb_mode_t function) { \ \ switch (function) { \ case PARANOIA_CB_READERR: \ cdda_read_error[n] = 1; \ break; \ default: \ break; \ } \ } #define ERROR_CB(n) cdda_paranoia_callback_##n /* These have to agree with the value of CDDA_DRIVES_MAX */ DEFINE_ERROR_CB(0) DEFINE_ERROR_CB(1) DEFINE_ERROR_CB(2) DEFINE_ERROR_CB(3) DEFINE_ERROR_CB(4) DEFINE_ERROR_CB(5) DEFINE_ERROR_CB(6) DEFINE_ERROR_CB(7) DEFINE_ERROR_CB(8) DEFINE_ERROR_CB(9) DEFINE_ERROR_CB(10) DEFINE_ERROR_CB(11) DEFINE_ERROR_CB(12) DEFINE_ERROR_CB(13) DEFINE_ERROR_CB(14) DEFINE_ERROR_CB(15) void cdda_reader_on_error(cdda_pdata_t * pd) { char flush_dest; cdda_drive_t * cdda_drive; pd->is_eos = 1; pd->pos_lsn = pd->last_lsn; while (rb_read_space(pd->rb)) rb_read(pd->rb, &flush_dest, sizeof(char)); cdda_drive = cdda_get_drive_by_device_path(pd->device_path); if (cdda_drive == NULL) { return; } cdda_drive->disc.hash_prev = cdda_drive->disc.hash; cdda_drive->disc.hash = 0L; } void * cdda_reader_thread(void * arg) { decoder_t * dec = (decoder_t *)arg; cdda_pdata_t * pd = (cdda_pdata_t *)dec->pdata; file_decoder_t * fdec = dec->fdec; cdda_drive_t * cdda_drive; int16_t * readbuf; int i; int n = cdda_get_n(pd->device_path); void(*callback)(long int, paranoia_cb_mode_t) = NULL; cdda_drive = cdda_get_drive_by_device_path(pd->device_path); if ((n < 0) || (cdda_drive == NULL)) { cdda_reader_on_error(pd); pd->cdda_reader_status = CDDA_READER_FREE; AQUALUNG_THREAD_DETACH() return NULL; } if (cdda_drive->disc.hash == 0L) { /* disc has been removed */ cdda_reader_on_error(pd); pd->cdda_reader_status = CDDA_READER_FREE; AQUALUNG_THREAD_DETACH() return NULL; } switch (n) { /* These have to agree with the value of CDDA_DRIVES_MAX */ case 0: callback = ERROR_CB(0); break; case 1: callback = ERROR_CB(1); break; case 2: callback = ERROR_CB(2); break; case 3: callback = ERROR_CB(3); break; case 4: callback = ERROR_CB(4); break; case 5: callback = ERROR_CB(5); break; case 6: callback = ERROR_CB(6); break; case 7: callback = ERROR_CB(7); break; case 8: callback = ERROR_CB(8); break; case 9: callback = ERROR_CB(9); break; case 10: callback = ERROR_CB(10); break; case 11: callback = ERROR_CB(11); break; case 12: callback = ERROR_CB(12); break; case 13: callback = ERROR_CB(13); break; case 14: callback = ERROR_CB(14); break; case 15: callback = ERROR_CB(15); break; } pd->paranoia = cdio_paranoia_init(pd->drive); cdio_paranoia_modeset(pd->paranoia, pd->paranoia_mode); cdio_paranoia_seek(pd->paranoia, pd->pos_lsn, SEEK_SET); while ((rb_write_space(pd->rb) > CDIO_CD_FRAMESIZE_RAW * 2) && (pd->pos_lsn < pd->disc_last_lsn)) { AQUALUNG_MUTEX_LOCK(pd->cdda_reader_mutex) if (pd->cdda_reader_status == CDDA_READER_FREE) { AQUALUNG_MUTEX_UNLOCK(pd->cdda_reader_mutex) pd->overread_sectors = 0; cdio_paranoia_free(pd->paranoia); return NULL; } AQUALUNG_MUTEX_UNLOCK(pd->cdda_reader_mutex) if (pd->paranoia_mode & PARANOIA_MODE_NEVERSKIP) { readbuf = cdio_paranoia_read(pd->paranoia, callback); } else { readbuf = cdio_paranoia_read_limited(pd->paranoia, callback, pd->paranoia_maxretries); } if (cdda_read_error[n]) { cdda_reader_on_error(pd); pd->cdda_reader_status = CDDA_READER_FREE; AQUALUNG_THREAD_DETACH() } if (pd->pos_lsn > pd->last_lsn) ++pd->overread_sectors; ++pd->pos_lsn; if (cdda_drive->swap_bytes) { for (i = 0; i < CDIO_CD_FRAMESIZE_RAW / 2; i++) { readbuf[i] = UINT16_SWAP_LE_BE_C(readbuf[i]); } } for (i = 0; i < CDIO_CD_FRAMESIZE_RAW / 2; i++) { float f = readbuf[i] / 32768.0 * fdec->voladj_lin; rb_write(pd->rb, (char *)&f, sample_size); } pd->is_eos = (pd->pos_lsn >= pd->last_lsn ? 1 : 0); } cdio_paranoia_free(pd->paranoia); AQUALUNG_MUTEX_LOCK(pd->cdda_reader_mutex) pd->cdda_reader_status = CDDA_READER_FREE; AQUALUNG_THREAD_DETACH() AQUALUNG_MUTEX_UNLOCK(pd->cdda_reader_mutex) return NULL; } decoder_t * cdda_decoder_init(file_decoder_t * fdec) { decoder_t * dec = NULL; #ifdef _WIN32 cdda_pdata_t * pd = NULL; #endif /* _WIN32 */ if ((dec = calloc(1, sizeof(decoder_t))) == NULL) { fprintf(stderr, "dec_cdda.c: cdda_decoder_new() failed: calloc error\n"); return NULL; } dec->fdec = fdec; if ((dec->pdata = calloc(1, sizeof(cdda_pdata_t))) == NULL) { fprintf(stderr, "dec_cdda.c: cdda_decoder_new() failed: calloc error\n"); return NULL; } dec->init = cdda_decoder_init; dec->destroy = cdda_decoder_destroy; dec->open = cdda_decoder_open; dec->send_metadata = cdda_decoder_send_metadata; dec->close = cdda_decoder_close; dec->read = cdda_decoder_read; dec->seek = cdda_decoder_seek; #ifdef _WIN32 pd = (cdda_pdata_t *)dec->pdata; pd->cdda_reader_mutex = g_mutex_new(); #endif /* _WIN32 */ return dec; } void cdda_decoder_destroy(decoder_t * dec) { #ifdef _WIN32 cdda_pdata_t * pd = (cdda_pdata_t *)dec->pdata; g_mutex_free(pd->cdda_reader_mutex); #endif /* _WIN32 */ free(dec->pdata); free(dec); } /* filename must be of format "CDDA " * e.g. "CDDA /dev/cdrom 6809B809 1" */ int cdda_decoder_open(decoder_t * dec, char * filename) { cdda_pdata_t * pd = (cdda_pdata_t *)dec->pdata; file_decoder_t * fdec = dec->fdec; unsigned int track; unsigned long hash; cdda_drive_t * drive; if (!cdda_is_cdtrack(filename)) { return DECODER_OPEN_BADLIB; } if (sscanf(filename, "CDDA %s %lX %u", pd->device_path, &hash, &track) < 3) { return DECODER_OPEN_BADLIB; } pd->track_no = track; drive = cdda_get_drive_by_device_path(pd->device_path); if (drive == NULL) { return DECODER_OPEN_FERROR; } if (drive->disc.hash != hash) { return DECODER_OPEN_FERROR; } if (drive->is_used) { fprintf(stderr, "cdda_decoder_open: drive %s is already in use\n", pd->device_path); return DECODER_OPEN_FERROR; } drive->is_used = 1; pd->cdio = cdio_open(pd->device_path, DRIVER_DEVICE); if (!pd->cdio) { printf("cdda_decoder_open: couldn't open cdio device %s\n", pd->device_path); drive->is_used = 0; return DECODER_OPEN_FERROR; } pd->drive = cdio_cddap_identify_cdio(pd->cdio, 0, NULL); if (!pd->drive) { printf("cdda_decoder_open: couldn't open drive %s\n", pd->device_path); drive->is_used = 0; cdio_destroy(pd->cdio); pd->cdio = NULL; return DECODER_OPEN_FERROR; } cdio_cddap_verbose_set(pd->drive, CDDA_MESSAGE_FORGETIT, CDDA_MESSAGE_FORGETIT); if (cdio_cddap_open(pd->drive) != 0) { printf("cdda_decoder_open: unable to open disc.\n"); drive->is_used = 0; cdio_cddap_close_no_free_cdio(pd->drive); pd->drive = NULL; cdio_destroy(pd->cdio); pd->cdio = NULL; return DECODER_OPEN_FERROR; } pd->first_lsn = cdio_cddap_track_firstsector(pd->drive, pd->track_no); pd->last_lsn = cdio_cddap_track_lastsector(pd->drive, pd->track_no); pd->disc_last_lsn = cdio_cddap_disc_lastsector(pd->drive); pd->pos_lsn = pd->first_lsn; pd->overread_sectors = 0; pd->is_eos = 0; if (drive->swap_bytes == -1) { drive->swap_bytes = data_bigendianp(pd->drive); } if (drive->swap_bytes == -1) { printf("cdda_decoder_open: unable to determine endianness of drive.\n"); drive->is_used = 0; cdio_cddap_close_no_free_cdio(pd->drive); pd->drive = NULL; cdio_destroy(pd->cdio); pd->cdio = NULL; return DECODER_OPEN_FERROR; } /* use this default in case cdda_decoder_set_mode() won't be called */ pd->paranoia_mode = PARANOIA_MODE_DISABLE; pd->rb = rb_create(2 * sample_size * RB_CDDA_SIZE); fdec->fileinfo.channels = 2; fdec->fileinfo.sample_rate = 44100; fdec->fileinfo.total_samples = (pd->last_lsn - pd->first_lsn + 1) * 588; fdec->file_lib = CDDA_LIB; fdec->fileinfo.bps = 2 * 16 * 44100; strcpy(dec->format_str, "Audio CD"); return DECODER_OPEN_SUCCESS; } void cdda_decoder_send_metadata(decoder_t * dec) { } /* set the next (pre-buffered) track on the same CD without closing */ int cdda_decoder_reopen(decoder_t * dec, char * filename) { cdda_pdata_t * pd = (cdda_pdata_t *)dec->pdata; file_decoder_t * fdec = dec->fdec; unsigned int track; unsigned long hash; cdda_drive_t * drive; if (!cdda_is_cdtrack(filename)) { return DECODER_OPEN_BADLIB; } if (sscanf(filename, "CDDA %s %lX %u", pd->device_path, &hash, &track) < 3) { return DECODER_OPEN_BADLIB; } pd->track_no = track; drive = cdda_get_drive_by_device_path(pd->device_path); if (drive == NULL) { return DECODER_OPEN_FERROR; } if (drive->disc.hash != hash) { drive->is_used = 0; return DECODER_OPEN_FERROR; } if (pd->overread_sectors > 0) { char flush_dest; while (rb_read_space(pd->rb) > pd->overread_sectors * CDIO_CD_FRAMESIZE_RAW * 2) rb_read(pd->rb, &flush_dest, sizeof(char)); } pd->first_lsn = cdio_cddap_track_firstsector(pd->drive, pd->track_no); pd->last_lsn = cdio_cddap_track_lastsector(pd->drive, pd->track_no); pd->pos_lsn = pd->first_lsn + pd->overread_sectors; pd->overread_sectors = 0; pd->is_eos = 0; fdec->fileinfo.total_samples = (pd->last_lsn - pd->first_lsn + 1) * 588; return DECODER_OPEN_SUCCESS; } void cdda_decoder_set_mode(decoder_t * dec, int drive_speed, int paranoia_mode, int paranoia_maxretries) { cdda_pdata_t * pd = (cdda_pdata_t *)dec->pdata; if (pd->cdio == NULL) return; if (cdio_set_speed(pd->cdio, drive_speed) != DRIVER_OP_SUCCESS) { fprintf(stderr, "Warning: setting CD drive speed seems to be unsupported.\n"); } pd->paranoia_mode = paranoia_mode; pd->paranoia_maxretries = paranoia_maxretries; } void cdda_decoder_close(decoder_t * dec) { cdda_pdata_t * pd = (cdda_pdata_t *)dec->pdata; cdda_drive_t * drive; AQUALUNG_MUTEX_LOCK(pd->cdda_reader_mutex) if (pd->cdda_reader_status == CDDA_READER_BUSY) { pd->cdda_reader_status = CDDA_READER_FREE; AQUALUNG_MUTEX_UNLOCK(pd->cdda_reader_mutex) AQUALUNG_THREAD_JOIN(pd->cdda_reader_id); } else { AQUALUNG_MUTEX_UNLOCK(pd->cdda_reader_mutex) } rb_free(pd->rb); cdio_cddap_close_no_free_cdio(pd->drive); pd->drive = NULL; cdio_set_speed(pd->cdio, 100); cdio_destroy(pd->cdio); pd->cdio = NULL; drive = cdda_get_drive_by_device_path(pd->device_path); if (drive == NULL) { return; } cdda_read_error[cdda_get_n(pd->device_path)] = 0; drive->is_used = 0; } unsigned int cdda_decoder_read(decoder_t * dec, float * dest, int num) { cdda_pdata_t * pd = (cdda_pdata_t *)dec->pdata; unsigned int numread = 0; unsigned int n_avail = 0; if ((rb_read_space(pd->rb) / sample_size < RB_CDDA_SIZE >> 2) && (!pd->is_eos)) { AQUALUNG_MUTEX_LOCK(pd->cdda_reader_mutex) if (pd->cdda_reader_status != CDDA_READER_BUSY) { pd->cdda_reader_status = CDDA_READER_BUSY; AQUALUNG_MUTEX_UNLOCK(pd->cdda_reader_mutex) AQUALUNG_THREAD_CREATE(pd->cdda_reader_id, NULL, cdda_reader_thread, dec) } else { AQUALUNG_MUTEX_UNLOCK(pd->cdda_reader_mutex) } } while ((rb_read_space(pd->rb) - (pd->overread_sectors * CDIO_CD_FRAMESIZE_RAW * 2) < num * 2 * sample_size) && (!pd->is_eos)) { struct timespec req; struct timespec rem; req.tv_sec = 0; req.tv_nsec = 100000000; /* 100 ms */ nanosleep(&req, &rem); } n_avail = (rb_read_space(pd->rb) - pd->overread_sectors * CDIO_CD_FRAMESIZE_RAW * 2) / (2 * sample_size); if (n_avail > num) n_avail = num; rb_read(pd->rb, (char *)dest, n_avail * 2 * sample_size); numread = n_avail; return numread; } void cdda_decoder_seek(decoder_t * dec, unsigned long long seek_to_pos) { cdda_pdata_t * pd = (cdda_pdata_t *)dec->pdata; file_decoder_t * fdec = dec->fdec; char flush_dest; AQUALUNG_MUTEX_LOCK(pd->cdda_reader_mutex) if (pd->cdda_reader_status == CDDA_READER_BUSY) { pd->cdda_reader_status = CDDA_READER_FREE; AQUALUNG_MUTEX_UNLOCK(pd->cdda_reader_mutex) AQUALUNG_THREAD_JOIN(pd->cdda_reader_id) } else { AQUALUNG_MUTEX_UNLOCK(pd->cdda_reader_mutex) } pd->pos_lsn = pd->first_lsn + seek_to_pos / 588; fdec->samples_left = fdec->fileinfo.total_samples - (seek_to_pos / 588) * 588; while (rb_read_space(pd->rb)) rb_read(pd->rb, &flush_dest, sizeof(char)); pd->overread_sectors = 0; AQUALUNG_MUTEX_LOCK(pd->cdda_reader_mutex) if ((pd->pos_lsn < pd->last_lsn) && (pd->cdda_reader_status == CDDA_READER_FREE)) { pd->cdda_reader_status = CDDA_READER_BUSY; AQUALUNG_MUTEX_UNLOCK(pd->cdda_reader_mutex) pd->is_eos = 0; AQUALUNG_THREAD_CREATE(pd->cdda_reader_id, NULL, cdda_reader_thread, dec) } else { AQUALUNG_MUTEX_UNLOCK(pd->cdda_reader_mutex) } } #else decoder_t * cdda_decoder_init(file_decoder_t * fdec) { return NULL; } #endif /* HAVE_CDDA */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/decoder/dec_flac.h0000644000175000001440000000506411243310677015210 00000000000000/* -*- linux-c -*- Copyright (C) 2005 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: dec_flac.h 1068 2009-07-24 12:02:30Z peterszilagyi $ */ #ifndef _DEC_FLAC_H #define _DEC_FLAC_H #ifdef HAVE_FLAC_8 #include #include #include #endif /* HAVE_FLAC_8 */ #ifdef HAVE_FLAC_7 #include #include #include #endif /* HAVE_FLAC_7 */ #include "file_decoder.h" /* size of ringbuffer for decoded FLAC data (in frames) */ #define RB_FLAC_SIZE 262144 #ifdef HAVE_FLAC_8 typedef struct _flac_pdata_t { FLAC__StreamDecoder * flac_decoder; rb_t * rb; int channels; int SR; unsigned bits_per_sample; FLAC__uint64 total_samples; int probing; /* whether we are reading for probing the file, or for real */ int error; FLAC__StreamDecoderState state; } flac_pdata_t; #endif /* HAVE_FLAC_8 */ #ifdef HAVE_FLAC_7 typedef struct _flac_pdata_t { FLAC__FileDecoder * flac_decoder; rb_t * rb; int channels; int SR; unsigned bits_per_sample; FLAC__uint64 total_samples; int probing; /* whether we are reading for probing the file, or for real */ int error; FLAC__FileDecoderState state; } flac_pdata_t; #endif /* HAVE_FLAC_7 */ decoder_t * flac_decoder_init(file_decoder_t * fdec); #ifdef HAVE_FLAC void flac_decoder_destroy(decoder_t * dec); int flac_decoder_open(decoder_t * dec, char * filename); void flac_decoder_send_metadata(decoder_t * dec); void flac_decoder_close(decoder_t * dec); unsigned int flac_decoder_read(decoder_t * dec, float * dest, int num); void flac_decoder_seek(decoder_t * dec, unsigned long long seek_to_pos); #endif /* HAVE_FLAC */ #endif /* _DEC_FLAC_H */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/decoder/dec_flac.c0000644000175000001440000005635411243310677015213 00000000000000/* -*- linux-c -*- Copyright (C) 2005 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: dec_flac.c 1068 2009-07-24 12:02:30Z peterszilagyi $ */ #include #include #include #include #include #include "../metadata_flac.h" #include "dec_flac.h" extern size_t sample_size; #ifdef HAVE_FLAC_8 /* FLAC write callback */ FLAC__StreamDecoderWriteStatus write_callback(const FLAC__StreamDecoder * decoder, const FLAC__Frame * frame, const FLAC__int32 * const buffer[], void * client_data) { decoder_t * dec = (decoder_t *) client_data; flac_pdata_t * pd = (flac_pdata_t *)dec->pdata; file_decoder_t * fdec = dec->fdec; int i, j; long int scale, blocksize; FLAC__int32 buf[2]; float fbuf[2]; if (pd->probing) return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; blocksize = frame->header.blocksize; scale = 1 << (pd->bits_per_sample - 1); for (i = 0; i < blocksize; i++) { for (j = 0; j < pd->channels; j++) { buf[j] = *(buffer[j] + i); fbuf[j] = (float)buf[j] * fdec->voladj_lin / scale; } rb_write(pd->rb, (char *)fbuf, pd->channels * sample_size); } return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; } /* FLAC metadata callback */ void metadata_callback(const FLAC__StreamDecoder * decoder, const FLAC__StreamMetadata * metadata, void * client_data) { decoder_t * dec = (decoder_t *)client_data; flac_pdata_t * pd = (flac_pdata_t *)dec->pdata; if (metadata->type == FLAC__METADATA_TYPE_STREAMINFO) { pd->SR = metadata->data.stream_info.sample_rate; pd->bits_per_sample = metadata->data.stream_info.bits_per_sample; pd->channels = metadata->data.stream_info.channels; pd->total_samples = metadata->data.stream_info.total_samples; } else { fprintf(stderr, "FLAC metadata callback: ignoring unexpected header\n"); } } /* FLAC error callback */ void error_callback(const FLAC__StreamDecoder * decoder, FLAC__StreamDecoderErrorStatus status, void * client_data) { decoder_t * dec = (decoder_t *) client_data; flac_pdata_t * pd = (flac_pdata_t *)dec->pdata; pd->error = 1; } #endif /* HAVE_FLAC_8 */ #ifdef HAVE_FLAC_7 /* FLAC write callback */ FLAC__StreamDecoderWriteStatus write_callback(const FLAC__FileDecoder * decoder, const FLAC__Frame * frame, const FLAC__int32 * const buffer[], void * client_data) { decoder_t * dec = (decoder_t *) client_data; flac_pdata_t * pd = (flac_pdata_t *)dec->pdata; file_decoder_t * fdec = dec->fdec; int i, j; long int scale, blocksize; FLAC__int32 buf[2]; float fbuf[2]; if (pd->probing) return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; blocksize = frame->header.blocksize; scale = 1 << (pd->bits_per_sample - 1); for (i = 0; i < blocksize; i++) { for (j = 0; j < pd->channels; j++) { buf[j] = *(buffer[j] + i); fbuf[j] = (float)buf[j] * fdec->voladj_lin / scale; } rb_write(pd->rb, (char *)fbuf, pd->channels * sample_size); } return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; } /* FLAC metadata callback */ void metadata_callback(const FLAC__FileDecoder * decoder, const FLAC__StreamMetadata * metadata, void * client_data) { decoder_t * dec = (decoder_t *)client_data; flac_pdata_t * pd = (flac_pdata_t *)dec->pdata; if (metadata->type == FLAC__METADATA_TYPE_STREAMINFO) { pd->SR = metadata->data.stream_info.sample_rate; pd->bits_per_sample = metadata->data.stream_info.bits_per_sample; pd->channels = metadata->data.stream_info.channels; pd->total_samples = metadata->data.stream_info.total_samples; } else { fprintf(stderr, "FLAC metadata callback: ignoring unexpected header\n"); } } /* FLAC error callback */ void error_callback(const FLAC__FileDecoder * decoder, FLAC__StreamDecoderErrorStatus status, void * client_data) { decoder_t * dec = (decoder_t *) client_data; flac_pdata_t * pd = (flac_pdata_t *)dec->pdata; pd->error = 1; } #endif /* HAVE_FLAC_7 */ #ifdef HAVE_FLAC decoder_t * flac_decoder_init(file_decoder_t * fdec) { decoder_t * dec = NULL; if ((dec = calloc(1, sizeof(decoder_t))) == NULL) { fprintf(stderr, "dec_flac.c: flac_decoder_new() failed: calloc error\n"); return NULL; } dec->fdec = fdec; if ((dec->pdata = calloc(1, sizeof(flac_pdata_t))) == NULL) { fprintf(stderr, "dec_flac.c: flac_decoder_new() failed: calloc error\n"); return NULL; } dec->init = flac_decoder_init; dec->destroy = flac_decoder_destroy; dec->open = flac_decoder_open; dec->send_metadata = flac_decoder_send_metadata; dec->close = flac_decoder_close; dec->read = flac_decoder_read; dec->seek = flac_decoder_seek; return dec; } void flac_decoder_destroy(decoder_t * dec) { free(dec->pdata); free(dec); } int flac_meta_vc_replace_or_append(file_decoder_t * fdec, FLAC__StreamMetadata * smeta) { FLAC__Metadata_SimpleIterator * iter; FLAC__bool ret; int found = 0; iter = FLAC__metadata_simple_iterator_new(); if (iter == NULL) { return META_ERROR_NOMEM; } ret = FLAC__metadata_simple_iterator_init(iter, fdec->filename, false, false); if (!ret) { fprintf(stderr, "dec_flac.c/flac_meta_replace_or_append: error: %s\n", FLAC__Metadata_SimpleIteratorStatusString[ FLAC__metadata_simple_iterator_status(iter)]); FLAC__metadata_simple_iterator_delete(iter); return META_ERROR_INTERNAL; } if (FLAC__metadata_simple_iterator_is_writable(iter) == false) { fprintf(stderr, "error: FLAC meta not writable!\n"); FLAC__metadata_simple_iterator_delete(iter); return META_ERROR_NOT_WRITABLE; } do { switch (FLAC__metadata_simple_iterator_get_block_type(iter)) { case FLAC__METADATA_TYPE_VORBIS_COMMENT: ret = FLAC__metadata_simple_iterator_set_block(iter, smeta, true); if (ret == false) { fprintf(stderr, "error: FLAC metadata write failed!\n"); FLAC__metadata_simple_iterator_delete(iter); return META_ERROR_INTERNAL; } found = 1; break; default: break; } } while (FLAC__metadata_simple_iterator_next(iter)); if (!found) { do { /* rewind to STREAMINFO and insert after that */ if (FLAC__metadata_simple_iterator_get_block_type(iter) == FLAC__METADATA_TYPE_STREAMINFO) { break; } } while (FLAC__metadata_simple_iterator_prev(iter)); ret = FLAC__metadata_simple_iterator_insert_block_after(iter, smeta, true); if (ret == false) { fprintf(stderr, "error: FLAC metadata write failed!\n"); FLAC__metadata_simple_iterator_delete(iter); return META_ERROR_INTERNAL; } } FLAC__metadata_simple_iterator_delete(iter); return META_ERROR_NONE; } #ifdef HAVE_FLAC_8 int flac_meta_append_pics(file_decoder_t * fdec, metadata_t * meta) { FLAC__Metadata_SimpleIterator * iter; FLAC__bool ret; meta_frame_t * frame; int found_vc = 0; iter = FLAC__metadata_simple_iterator_new(); if (iter == NULL) { return META_ERROR_NOMEM; } ret = FLAC__metadata_simple_iterator_init(iter, fdec->filename, false, false); if (!ret) { fprintf(stderr, "dec_flac.c/flac_meta_append_pics: error: %s\n", FLAC__Metadata_SimpleIteratorStatusString[ FLAC__metadata_simple_iterator_status(iter)]); FLAC__metadata_simple_iterator_delete(iter); return META_ERROR_INTERNAL; } if (FLAC__metadata_simple_iterator_is_writable(iter) == false) { fprintf(stderr, "error: FLAC meta not writable!\n"); FLAC__metadata_simple_iterator_delete(iter); return META_ERROR_NOT_WRITABLE; } /* try to insert pictures after the Vorbis Comment, or if there is none, after STREAMINFO. */ do { if (FLAC__metadata_simple_iterator_get_block_type(iter) == FLAC__METADATA_TYPE_VORBIS_COMMENT) { found_vc = 1; break; } } while (FLAC__metadata_simple_iterator_next(iter)); if (!found_vc) { do { /* rewind to STREAMINFO and insert after that */ if (FLAC__metadata_simple_iterator_get_block_type(iter) == FLAC__METADATA_TYPE_STREAMINFO) { break; } } while (FLAC__metadata_simple_iterator_prev(iter)); } frame = metadata_get_frame_by_tag(meta, META_TAG_FLAC_APIC, NULL); while (frame) { FLAC__StreamMetadata * smeta = metadata_apic_frame_to_smeta(frame); ret = FLAC__metadata_simple_iterator_insert_block_after(iter, smeta, true); if (ret == false) { fprintf(stderr, "error: FLAC metadata write failed!\n"); FLAC__metadata_object_delete(smeta); FLAC__metadata_simple_iterator_delete(iter); return META_ERROR_INTERNAL; } FLAC__metadata_object_delete(smeta); frame = metadata_get_frame_by_tag(meta, META_TAG_FLAC_APIC, frame); } FLAC__metadata_simple_iterator_delete(iter); return META_ERROR_NONE; } #endif /* HAVE_FLAC_8 */ int flac_meta_delete(file_decoder_t * fdec, int del_vc) { FLAC__Metadata_SimpleIterator * iter; FLAC__bool ret; iter = FLAC__metadata_simple_iterator_new(); if (iter == NULL) { return META_ERROR_NOMEM; } ret = FLAC__metadata_simple_iterator_init(iter, fdec->filename, false, false); if (!ret) { fprintf(stderr, "dec_flac.c/flac_meta_delete: error: %s\n", FLAC__Metadata_SimpleIteratorStatusString[ FLAC__metadata_simple_iterator_status(iter)]); FLAC__metadata_simple_iterator_delete(iter); return META_ERROR_INTERNAL; } if (FLAC__metadata_simple_iterator_is_writable(iter) == false) { fprintf(stderr, "error: FLAC meta not writable!\n"); FLAC__metadata_simple_iterator_delete(iter); return META_ERROR_NOT_WRITABLE; } do { switch (FLAC__metadata_simple_iterator_get_block_type(iter)) { case FLAC__METADATA_TYPE_VORBIS_COMMENT: if (!del_vc) break; ret = FLAC__metadata_simple_iterator_delete_block(iter, true); if (ret == false) { fprintf(stderr, "error: FLAC metadata delete failed!\n"); FLAC__metadata_simple_iterator_delete(iter); return META_ERROR_INTERNAL; } break; #ifdef HAVE_FLAC_8 case FLAC__METADATA_TYPE_PICTURE: ret = FLAC__metadata_simple_iterator_delete_block(iter, true); if (ret == false) { fprintf(stderr, "error: FLAC metadata delete failed!\n"); FLAC__metadata_simple_iterator_delete(iter); return META_ERROR_INTERNAL; } break; #endif /* HAVE_FLAC_8 */ default: break; } } while (FLAC__metadata_simple_iterator_next(iter)); FLAC__metadata_simple_iterator_delete(iter); return META_ERROR_NONE; } int flac_write_metadata(file_decoder_t * fdec, metadata_t * meta) { int ret; int del_vc = 0; if (metadata_get_frame_by_tag(meta, META_TAG_OXC, NULL) == NULL) { /* no Ogg Xiph comment in this metablock -- remove it from file */ del_vc = 1; } ret = flac_meta_delete(fdec, del_vc); if (ret != META_ERROR_NONE) { return ret; } if (!del_vc) { FLAC__StreamMetadata * smeta = metadata_to_flac_streammeta(meta); ret = flac_meta_vc_replace_or_append(fdec, smeta); if (ret != META_ERROR_NONE) { return ret; } FLAC__metadata_object_delete(smeta); } #ifdef HAVE_FLAC_8 if (metadata_get_frame_by_tag(meta, META_TAG_FLAC_APIC, NULL) != NULL) { ret = flac_meta_append_pics(fdec, meta); if (ret != META_ERROR_NONE) { return ret; } } #endif /* HAVE_FLAC_8 */ return META_ERROR_NONE; } void flac_send_metadata(decoder_t * dec) { file_decoder_t * fdec = dec->fdec; metadata_t * meta; int found = 0; int writable; FLAC__Metadata_SimpleIterator * iter; FLAC__bool ret; iter = FLAC__metadata_simple_iterator_new(); if (iter == NULL) { return; } writable = (access(fdec->filename, R_OK | W_OK) == 0) ? 1 : 0; ret = FLAC__metadata_simple_iterator_init(iter, fdec->filename, writable ? false : true, false); if (!ret) { fprintf(stderr, "dec_flac.c/flac_send_metadata: error: %s\n", FLAC__Metadata_SimpleIteratorStatusString[ FLAC__metadata_simple_iterator_status(iter)]); FLAC__metadata_simple_iterator_delete(iter); return; } meta = metadata_new(); meta->fdec = fdec; fdec->meta = meta; #ifdef HAVE_FLAC_8 meta->valid_tags = META_TAG_OXC | META_TAG_FLAC_APIC; #else meta->valid_tags = META_TAG_OXC; #endif /* HAVE_FLAC_8 */ if (writable && FLAC__metadata_simple_iterator_is_writable(iter) == true) { meta->writable = 1; fdec->meta_write = flac_write_metadata; } do { FLAC__StreamMetadata * smeta; switch (FLAC__metadata_simple_iterator_get_block_type(iter)) { case FLAC__METADATA_TYPE_VORBIS_COMMENT: smeta = FLAC__metadata_simple_iterator_get_block(iter); FLAC__StreamMetadata_VorbisComment vc = FLAC__metadata_simple_iterator_get_block(iter)->data.vorbis_comment; metadata_from_flac_streammeta_vc(meta, &vc); found = 1; FLAC__metadata_object_delete(smeta); break; #ifdef HAVE_FLAC_8 case FLAC__METADATA_TYPE_PICTURE: smeta = FLAC__metadata_simple_iterator_get_block(iter); FLAC__StreamMetadata_Picture pic = FLAC__metadata_simple_iterator_get_block(iter)->data.picture; metadata_from_flac_streammeta_pic(meta, &pic); found = 1; FLAC__metadata_object_delete(smeta); break; #endif /* HAVE_FLAC_8 */ default: break; } } while (FLAC__metadata_simple_iterator_next(iter)); FLAC__metadata_simple_iterator_delete(iter); if (!found && !meta->writable) { fdec->meta = NULL; metadata_free(meta); } } #endif /* HAVE_FLAC */ #ifdef HAVE_FLAC_8 int flac_decoder_open(decoder_t * dec, char * filename) { flac_pdata_t * pd = (flac_pdata_t *)dec->pdata; file_decoder_t * fdec = dec->fdec; int tried_flac = 0; try_flac: pd->error = 0; pd->flac_decoder = FLAC__stream_decoder_new(); if ((pd->state = FLAC__stream_decoder_init_file(pd->flac_decoder, filename, write_callback, metadata_callback, error_callback, (void *)dec)) != FLAC__STREAM_DECODER_INIT_STATUS_OK) { FLAC__stream_decoder_delete(pd->flac_decoder); return DECODER_OPEN_FERROR; } FLAC__stream_decoder_process_until_end_of_metadata(pd->flac_decoder); if ((!pd->error) && (pd->channels > 0)) { if ((pd->channels != 1) && (pd->channels != 2)) { fprintf(stderr, "flac_decoder_open: FLAC file with %d channels is " "unsupported\n", pd->channels); return DECODER_OPEN_FERROR; } else { if (!tried_flac) { /* we need a real read test (some MP3's get to this point) */ pd->probing = 1; FLAC__stream_decoder_process_single(pd->flac_decoder); pd->state = FLAC__stream_decoder_get_state(pd->flac_decoder); if ((pd->state != FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC) && (pd->state != FLAC__STREAM_DECODER_SEARCH_FOR_METADATA) && (pd->state != FLAC__STREAM_DECODER_READ_METADATA) && (pd->state != FLAC__STREAM_DECODER_READ_FRAME)) { return DECODER_OPEN_BADLIB; } pd->probing = 0; tried_flac = 1; FLAC__stream_decoder_finish(pd->flac_decoder); FLAC__stream_decoder_delete(pd->flac_decoder); goto try_flac; } pd->rb = rb_create(pd->channels * sample_size * RB_FLAC_SIZE); fdec->fileinfo.channels = pd->channels; fdec->fileinfo.sample_rate = pd->SR; fdec->fileinfo.total_samples = pd->total_samples; fdec->fileinfo.bps = pd->bits_per_sample * fdec->fileinfo.sample_rate * fdec->fileinfo.channels; fdec->file_lib = FLAC_LIB; strcpy(dec->format_str, "FLAC"); flac_send_metadata(dec); return DECODER_OPEN_SUCCESS; } } else { FLAC__stream_decoder_finish(pd->flac_decoder); FLAC__stream_decoder_delete(pd->flac_decoder); return DECODER_OPEN_BADLIB; } } #endif /* HAVE_FLAC_8 */ #ifdef HAVE_FLAC_7 int flac_decoder_open(decoder_t * dec, char * filename) { flac_pdata_t * pd = (flac_pdata_t *)dec->pdata; file_decoder_t * fdec = dec->fdec; int tried_flac = 0; try_flac: pd->error = 0; pd->flac_decoder = FLAC__file_decoder_new(); FLAC__file_decoder_set_client_data(pd->flac_decoder, (void *)dec); FLAC__file_decoder_set_write_callback(pd->flac_decoder, write_callback); FLAC__file_decoder_set_metadata_callback(pd->flac_decoder, metadata_callback); FLAC__file_decoder_set_error_callback(pd->flac_decoder, error_callback); FLAC__file_decoder_set_filename(pd->flac_decoder, filename); if (FLAC__file_decoder_init(pd->flac_decoder)) { FLAC__file_decoder_delete(pd->flac_decoder); return DECODER_OPEN_FERROR; } FLAC__file_decoder_process_until_end_of_metadata(pd->flac_decoder); if ((!pd->error) && (pd->channels > 0)) { if ((pd->channels != 1) && (pd->channels != 2)) { fprintf(stderr, "flac_decoder_open: FLAC file with %d channels is " "unsupported\n", pd->channels); return DECODER_OPEN_FERROR; } else { if (!tried_flac) { /* we need a real read test (some MP3's get to this point) */ pd->probing = 1; FLAC__file_decoder_process_single(pd->flac_decoder); pd->state = FLAC__file_decoder_get_state(pd->flac_decoder); if ((pd->state != FLAC__FILE_DECODER_OK) && (pd->state != FLAC__FILE_DECODER_END_OF_FILE)) { return DECODER_OPEN_BADLIB; } pd->probing = 0; tried_flac = 1; FLAC__file_decoder_finish(pd->flac_decoder); FLAC__file_decoder_delete(pd->flac_decoder); goto try_flac; } pd->rb = rb_create(pd->channels * sample_size * RB_FLAC_SIZE); fdec->fileinfo.channels = pd->channels; fdec->fileinfo.sample_rate = pd->SR; fdec->fileinfo.total_samples = pd->total_samples; fdec->fileinfo.bps = pd->bits_per_sample * fdec->fileinfo.sample_rate * fdec->fileinfo.channels; fdec->file_lib = FLAC_LIB; strcpy(dec->format_str, "FLAC"); flac_send_metadata(dec); return DECODER_OPEN_SUCCESS; } } else { FLAC__file_decoder_finish(pd->flac_decoder); FLAC__file_decoder_delete(pd->flac_decoder); return DECODER_OPEN_BADLIB; } } #endif /* HAVE_FLAC_7 */ void flac_decoder_send_metadata(decoder_t * dec) { file_decoder_t * fdec = dec->fdec; if (fdec->meta != NULL && fdec->meta_cb != NULL) { fdec->meta_cb(fdec->meta, fdec->meta_cbdata); } } #ifdef HAVE_FLAC_8 void flac_decoder_close(decoder_t * dec) { flac_pdata_t * pd = (flac_pdata_t *)dec->pdata; FLAC__stream_decoder_finish(pd->flac_decoder); FLAC__stream_decoder_delete(pd->flac_decoder); rb_free(pd->rb); } #endif /* HAVE_FLAC_8 */ #ifdef HAVE_FLAC_7 void flac_decoder_close(decoder_t * dec) { flac_pdata_t * pd = (flac_pdata_t *)dec->pdata; FLAC__file_decoder_finish(pd->flac_decoder); FLAC__file_decoder_delete(pd->flac_decoder); rb_free(pd->rb); } #endif /* HAVE_FLAC_7 */ #ifdef HAVE_FLAC_8 unsigned int flac_decoder_read(decoder_t * dec, float * dest, int num) { flac_pdata_t * pd = (flac_pdata_t *)dec->pdata; unsigned int numread = 0; unsigned int n_avail = 0; pd->state = FLAC__stream_decoder_get_state(pd->flac_decoder); while ((rb_read_space(pd->rb) < num * pd->channels * sample_size) && (pd->state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC || pd->state == FLAC__STREAM_DECODER_SEARCH_FOR_METADATA || pd->state == FLAC__STREAM_DECODER_READ_METADATA || pd->state == FLAC__STREAM_DECODER_READ_FRAME)) { FLAC__stream_decoder_process_single(pd->flac_decoder); pd->state = FLAC__stream_decoder_get_state(pd->flac_decoder); } /* Have i chosen the right conditions? */ if ((pd->state != FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC) && (pd->state != FLAC__STREAM_DECODER_SEARCH_FOR_METADATA) && (pd->state != FLAC__STREAM_DECODER_READ_METADATA) && (pd->state != FLAC__STREAM_DECODER_READ_FRAME) && (pd->state != FLAC__STREAM_DECODER_END_OF_STREAM)) { fprintf(stderr, "file_decoder_read() / FLAC: decoder error: %s\n", FLAC__StreamDecoderStateString[pd->state]); return 0; /* this means that a new file will be opened */ } n_avail = rb_read_space(pd->rb) / (pd->channels * sample_size); if (n_avail > num) { n_avail = num; } rb_read(pd->rb, (char *)dest, n_avail * pd->channels * sample_size); numread = n_avail; return numread; } #endif /* HAVE_FLAC_8 */ #ifdef HAVE_FLAC_7 unsigned int flac_decoder_read(decoder_t * dec, float * dest, int num) { flac_pdata_t * pd = (flac_pdata_t *)dec->pdata; unsigned int numread = 0; unsigned int n_avail = 0; pd->state = FLAC__file_decoder_get_state(pd->flac_decoder); while ((rb_read_space(pd->rb) < num * pd->channels * sample_size) && (pd->state == FLAC__FILE_DECODER_OK)) { FLAC__file_decoder_process_single(pd->flac_decoder); pd->state = FLAC__file_decoder_get_state(pd->flac_decoder); } if ((pd->state != FLAC__FILE_DECODER_OK) && (pd->state != FLAC__FILE_DECODER_END_OF_FILE)) { fprintf(stderr, "file_decoder_read() / FLAC: decoder error: %s\n", FLAC__FileDecoderStateString[pd->state]); return 0; /* this means that a new file will be opened */ } n_avail = rb_read_space(pd->rb) / (pd->channels * sample_size); if (n_avail > num) { n_avail = num; } rb_read(pd->rb, (char *)dest, n_avail * pd->channels * sample_size); numread = n_avail; return numread; } #endif /* HAVE_FLAC_7 */ #ifdef HAVE_FLAC_8 void flac_decoder_seek(decoder_t * dec, unsigned long long seek_to_pos) { flac_pdata_t * pd = (flac_pdata_t *)dec->pdata; file_decoder_t * fdec = dec->fdec; char flush_dest; if (seek_to_pos == fdec->fileinfo.total_samples) { --seek_to_pos; } if (FLAC__stream_decoder_seek_absolute(pd->flac_decoder, seek_to_pos)) { fdec->samples_left = fdec->fileinfo.total_samples - seek_to_pos; /* empty flac decoder ringbuffer */ while (rb_read_space(pd->rb)) rb_read(pd->rb, &flush_dest, sizeof(char)); } else { fprintf(stderr, "flac_decoder_seek: warning: " "FLAC__file_decoder_seek_absolute() failed\n"); } } #endif /* HAVE_FLAC_8 */ #ifdef HAVE_FLAC_7 void flac_decoder_seek(decoder_t * dec, unsigned long long seek_to_pos) { flac_pdata_t * pd = (flac_pdata_t *)dec->pdata; file_decoder_t * fdec = dec->fdec; char flush_dest; if (seek_to_pos == fdec->fileinfo.total_samples) { --seek_to_pos; } if (FLAC__file_decoder_seek_absolute(pd->flac_decoder, seek_to_pos)) { fdec->samples_left = fdec->fileinfo.total_samples - seek_to_pos; /* empty flac decoder ringbuffer */ while (rb_read_space(pd->rb)) rb_read(pd->rb, &flush_dest, sizeof(char)); } else { fprintf(stderr, "stream_decoder_seek: warning: " "FLAC__stream_decoder_seek_absolute() failed\n"); } } #endif /* HAVE_FLAC_7 */ #ifndef HAVE_FLAC decoder_t * flac_decoder_init(file_decoder_t * fdec) { return NULL; } #endif /* !HAVE_FLAC */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/decoder/dec_lavc.h0000644000175000001440000000446111243310677015230 00000000000000/* -*- linux-c -*- Copyright (C) 2005 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: dec_lavc.h 1068 2009-07-24 12:02:30Z peterszilagyi $ */ #ifndef _DEC_LAVC_H #define _DEC_LAVC_H #ifdef HAVE_LAVC #ifdef HAVE_FFMPEG_LIBAVCODEC_AVCODEC_H #include #elif defined HAVE_LIBAVCODEC_AVCODEC_H #include #elif defined HAVE_FFMPEG_AVCODEC_H #include #elif defined HAVE_AVCODEC_H #include #endif #ifdef HAVE_FFMPEG_LIBAVFORMAT_AVFORMAT_H #include #elif defined HAVE_LIBAVFORMAT_AVFORMAT_H #include #elif defined HAVE_FFMPEG_AVFORMAT_H #include #elif defined AVFORMAT_H #include #endif #endif /* HAVE_LAVC */ #include "file_decoder.h" #ifdef HAVE_LAVC #define RB_LAVC_SIZE (3*AVCODEC_MAX_AUDIO_FRAME_SIZE) typedef struct _lavc_pdata_t { rb_t * rb; AVFormatContext * avFormatCtx; AVCodecContext * avCodecCtx; AVCodec * avCodec; AVRational time_base; int audioStream; int is_eos; } lavc_pdata_t; #endif /* HAVE_LAVC */ decoder_t * lavc_decoder_init(file_decoder_t * fdec); #ifdef HAVE_LAVC void lavc_decoder_destroy(decoder_t * dec); int lavc_decoder_open(decoder_t * dec, char * filename); void lavc_decoder_send_metadata(decoder_t * dec); void lavc_decoder_close(decoder_t * dec); unsigned int lavc_decoder_read(decoder_t * dec, float * dest, int num); void lavc_decoder_seek(decoder_t * dec, unsigned long long seek_to_pos); #endif /* HAVE_LAVC */ #endif /* _DEC_LAVC_H */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/decoder/dec_lavc.c0000644000175000001440000001471311243310677015224 00000000000000/* -*- linux-c -*- Copyright (C) 2005 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: dec_lavc.c 1068 2009-07-24 12:02:30Z peterszilagyi $ */ #include #include #include #include #include #include "dec_lavc.h" #ifdef HAVE_LAVC /* uncomment this to get some debug info */ /* #define LAVC_DEBUG */ extern size_t sample_size; /* return 1 if reached end of stream, 0 else */ int decode_lavc(decoder_t * dec) { lavc_pdata_t * pd = (lavc_pdata_t *)dec->pdata; file_decoder_t * fdec = dec->fdec; AVPacket packet; int16_t samples[AVCODEC_MAX_AUDIO_FRAME_SIZE]; float fsamples[AVCODEC_MAX_AUDIO_FRAME_SIZE]; int n_bytes = AVCODEC_MAX_AUDIO_FRAME_SIZE; if (av_read_frame(pd->avFormatCtx, &packet) < 0) return 1; if (packet.stream_index == pd->audioStream) { avcodec_decode_audio2(pd->avCodecCtx, samples, &n_bytes, packet.data, packet.size); if (n_bytes > 0) { int i; for (i = 0; i < n_bytes/2; i++) { fsamples[i] = samples[i] * fdec->voladj_lin / 32768.f; } rb_write(pd->rb, (char *)fsamples, n_bytes/2 * sample_size); } } av_free_packet(&packet); return 0; } decoder_t * lavc_decoder_init(file_decoder_t * fdec) { decoder_t * dec = NULL; if ((dec = calloc(1, sizeof(decoder_t))) == NULL) { fprintf(stderr, "dec_lavc.c: lavc_decoder_new() failed: calloc error\n"); return NULL; } dec->fdec = fdec; if ((dec->pdata = calloc(1, sizeof(lavc_pdata_t))) == NULL) { fprintf(stderr, "dec_lavc.c: lavc_decoder_new() failed: calloc error\n"); return NULL; } dec->init = lavc_decoder_init; dec->destroy = lavc_decoder_destroy; dec->open = lavc_decoder_open; dec->send_metadata = lavc_decoder_send_metadata; dec->close = lavc_decoder_close; dec->read = lavc_decoder_read; dec->seek = lavc_decoder_seek; return dec; } void lavc_decoder_destroy(decoder_t * dec) { free(dec->pdata); free(dec); } int lavc_decoder_open(decoder_t * dec, char * filename) { lavc_pdata_t * pd = (lavc_pdata_t *)dec->pdata; file_decoder_t * fdec = dec->fdec; int i; if (av_open_input_file(&pd->avFormatCtx, filename, NULL, 0, NULL) != 0) return DECODER_OPEN_BADLIB; if (av_find_stream_info(pd->avFormatCtx) < 0) return DECODER_OPEN_BADLIB; /* debug */ #ifdef LAVC_DEBUG dump_format(pd->avFormatCtx, 0, filename, 0); #endif /* LAVC_DEBUG */ pd->audioStream = -1; for (i = 0; i < pd->avFormatCtx->nb_streams; i++) { if (pd->avFormatCtx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO) { pd->audioStream = i; break; } } if (pd->audioStream == -1) return DECODER_OPEN_BADLIB; pd->avCodecCtx = pd->avFormatCtx->streams[pd->audioStream]->codec; pd->time_base = pd->avFormatCtx->streams[pd->audioStream]->time_base; pd->avCodec = avcodec_find_decoder(pd->avCodecCtx->codec_id); if (pd->avCodec == NULL) return DECODER_OPEN_BADLIB; if (avcodec_open(pd->avCodecCtx, pd->avCodec) < 0) return DECODER_OPEN_BADLIB; if ((pd->avCodecCtx->channels != 1) && (pd->avCodecCtx->channels != 2)) { fprintf(stderr, "lavc_decoder_open: audio stream with %d channels is unsupported\n", pd->avCodecCtx->channels); return DECODER_OPEN_FERROR; } pd->is_eos = 0; pd->rb = rb_create(pd->avCodecCtx->channels * sample_size * RB_LAVC_SIZE); fdec->fileinfo.channels = pd->avCodecCtx->channels; fdec->fileinfo.sample_rate = pd->avCodecCtx->sample_rate; fdec->fileinfo.bps = pd->avCodecCtx->bit_rate; if (pd->avFormatCtx->duration > 0) { fdec->fileinfo.total_samples = pd->avFormatCtx->duration / 1000000.0 * pd->avCodecCtx->sample_rate; } else { fdec->fileinfo.total_samples = 0; } fdec->file_lib = LAVC_LIB; snprintf(dec->format_str, MAXLEN-1, "%s/%s", pd->avFormatCtx->iformat->name, pd->avCodec->name); for (i = 0; dec->format_str[i] != '\0'; i++) { dec->format_str[i] = toupper(dec->format_str[i]); } return DECODER_OPEN_SUCCESS; } void lavc_decoder_send_metadata(decoder_t * dec) { } void lavc_decoder_close(decoder_t * dec) { lavc_pdata_t * pd = (lavc_pdata_t *)dec->pdata; avcodec_close(pd->avCodecCtx); av_close_input_file(pd->avFormatCtx); rb_free(pd->rb); } unsigned int lavc_decoder_read(decoder_t * dec, float * dest, int num) { lavc_pdata_t * pd = (lavc_pdata_t *)dec->pdata; unsigned int numread = 0; unsigned int n_avail = 0; while ((rb_read_space(pd->rb) < num * pd->avCodecCtx->channels * sample_size) && (!pd->is_eos)) { pd->is_eos = decode_lavc(dec); } n_avail = rb_read_space(pd->rb) / (pd->avCodecCtx->channels * sample_size); if (n_avail > num) n_avail = num; rb_read(pd->rb, (char *)dest, n_avail * pd->avCodecCtx->channels * sample_size); numread = n_avail; return numread; } void lavc_decoder_seek(decoder_t * dec, unsigned long long seek_to_pos) { lavc_pdata_t * pd = (lavc_pdata_t *)dec->pdata; file_decoder_t * fdec = dec->fdec; char flush_dest; long long pos = fdec->fileinfo.total_samples - fdec->samples_left; int64_t timestamp = (double)seek_to_pos / fdec->fileinfo.sample_rate * pd->time_base.den / pd->time_base.num; int flags = (pos > seek_to_pos) ? AVSEEK_FLAG_BACKWARD : 0; if (av_seek_frame(pd->avFormatCtx, pd->audioStream, timestamp, flags) >= 0) { fdec->samples_left = fdec->fileinfo.total_samples - seek_to_pos; /* empty lavc decoder ringbuffer */ while (rb_read_space(pd->rb)) rb_read(pd->rb, &flush_dest, sizeof(char)); } else { fprintf(stderr, "lavc_decoder_seek: warning: av_seek_frame() failed\n"); } } #else decoder_t * lavc_decoder_init(file_decoder_t * fdec) { return NULL; } #endif /* HAVE_LAVC */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/decoder/dec_mac.h0000644000175000001440000000401711243310677015040 00000000000000/* -*- linux-c -*- Copyright (C) 2005 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: dec_mac.h 1068 2009-07-24 12:02:30Z peterszilagyi $ */ #ifndef _DEC_MAC_H #define _DEC_MAC_H #include "file_decoder.h" /* Decoding buffer size for Monkey's Audio */ #define MAC_BUFSIZE 9216 /* size of ringbuffer for decoded Monkey's Audio data (in frames) */ #define RB_MAC_SIZE 262144 #ifdef HAVE_MAC typedef struct _mac_pdata_t { rb_t * rb; void * decompress; /* (IAPEDecompress *) */ unsigned int sample_rate; unsigned int bits_per_sample; unsigned int bitrate; unsigned int channels; unsigned int length_in_ms; unsigned int block_align; unsigned int compression_level; int swap_bytes; int is_eos; } mac_pdata_t; #endif /* HAVE_MAC */ #ifdef __cplusplus extern "C"{ #endif decoder_t * mac_decoder_init(file_decoder_t * fdec); #ifdef HAVE_MAC void mac_decoder_destroy(decoder_t * dec); int mac_decoder_open(decoder_t * dec, char * filename); void mac_decoder_send_metadata(decoder_t * dec ); void mac_decoder_close(decoder_t * dec); unsigned int mac_decoder_read(decoder_t * dec, float * dest, int num); void mac_decoder_seek(decoder_t * dec, unsigned long long seek_to_pos); #endif /* HAVE_MAC */ #ifdef __cplusplus } #endif #endif /* _DEC_MAC_H */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/decoder/dec_mac.cpp0000644000175000001440000002110711243310677015372 00000000000000/* -*- linux-c -*- Copyright (C) 2005 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: dec_mac.cpp 1068 2009-07-24 12:02:30Z peterszilagyi $ */ #include #include #include #ifdef HAVE_MAC /* expand this to nothing so there's no error when including MACLib.h */ /* -- talkin' about cross-platform libraries? */ #define DLLEXPORT /* undefine these to avoid clashes... */ #undef PACKAGE #undef PACKAGE_BUGREPORT #undef PACKAGE_NAME #undef PACKAGE_STRING #undef PACKAGE_TARNAME #undef PACKAGE_VERSION #undef VERSION /* more cross-platform compatibility... */ #include #include #include #include /* undefine these to avoid clashes... */ #undef PACKAGE #undef PACKAGE_BUGREPORT #undef PACKAGE_NAME #undef PACKAGE_STRING #undef PACKAGE_TARNAME #undef PACKAGE_VERSION #undef VERSION #endif /* HAVE_MAC */ extern "C" { #include "../i18n.h" #include "../metadata_ape.h" #include "dec_mac.h" } extern size_t sample_size; #define SAMPLES_PER_READ 2048 #ifdef HAVE_MAC #define SWAP_16(x) ((((x)&0x00ff)<<8) | (((x)&0xff00)>>8)) #define SWAP_32(x) ((((x)&0xff)<<24) | (((x)&0xff00)<<8) | (((x)&0xff0000)>>8) | (((x)&0xff000000)>>24)) /* return 1 if reached end of stream, 0 else */ int decode_mac(decoder_t * dec) { mac_pdata_t * pd = (mac_pdata_t *)dec->pdata; file_decoder_t * fdec = dec->fdec; IAPEDecompress * pdecompress = (IAPEDecompress *)pd->decompress; int blocks_to_read = SAMPLES_PER_READ; int bytes = blocks_to_read * pd->block_align; int act_read, act_bytes; unsigned long scale = 1 << (pd->bits_per_sample - 1); float fbuf[2 * SAMPLES_PER_READ]; int n = 0; act_read = blocks_to_read; act_bytes = bytes; switch (pd->bits_per_sample) { case 8: char data8[2 * SAMPLES_PER_READ]; pdecompress->GetData(data8, blocks_to_read, &act_read); if (!act_read) { return 1; } for (int i = 0; i < act_read; i++) { for (unsigned int j = 0; j < pd->channels; j++) { fbuf[n] = (float)(data8[n] * fdec->voladj_lin / scale); ++n; } } break; case 16: short data16[2 * SAMPLES_PER_READ]; pdecompress->GetData((char *)data16, blocks_to_read, &act_read); if (!act_read) { return 1; } for (int i = 0; i < act_read; i++) { for (unsigned int j = 0; j < pd->channels; j++) { if (pd->swap_bytes) data16[n] = SWAP_16(data16[n]); fbuf[n] = (float)(data16[n] * fdec->voladj_lin / scale); ++n; } } break; case 32: int data32[2 * SAMPLES_PER_READ]; pdecompress->GetData((char *)data32, blocks_to_read, &act_read); if (!act_read) { return 1; } for (int i = 0; i < act_read; i++) { for (unsigned int j = 0; j < pd->channels; j++) { if (pd->swap_bytes) data32[n] = SWAP_32(data32[n]); fbuf[n] = (float)(data32[n] * fdec->voladj_lin / scale); ++n; } } break; default: printf("programmer error, please report: invalid bits_per_sample = %d " "in decode_mac()\n", pd->bits_per_sample); break; } rb_write(pd->rb, (char *)fbuf, act_read * pd->channels * sample_size); return 0; } decoder_t * mac_decoder_init(file_decoder_t * fdec) { decoder_t * dec = NULL; if ((dec = (decoder_t *)calloc(1, sizeof(decoder_t))) == NULL) { fprintf(stderr, "dec_mac.c: mac_decoder_new() failed: calloc error\n"); return NULL; } dec->fdec = fdec; if ((dec->pdata = calloc(1, sizeof(mac_pdata_t))) == NULL) { fprintf(stderr, "dec_mac.c: mac_decoder_new() failed: calloc error\n"); return NULL; } dec->init = mac_decoder_init; dec->destroy = mac_decoder_destroy; dec->open = mac_decoder_open; dec->send_metadata = mac_decoder_send_metadata; dec->close = mac_decoder_close; dec->read = mac_decoder_read; dec->seek = mac_decoder_seek; return dec; } void mac_decoder_destroy(decoder_t * dec) { free(dec->pdata); free(dec); } int mac_decoder_open(decoder_t * dec, char * filename) { mac_pdata_t * pd = (mac_pdata_t *)dec->pdata; file_decoder_t * fdec = dec->fdec; metadata_t * meta; IAPEDecompress * pdecompress = (IAPEDecompress *)pd->decompress; int ret = 0; wchar_t * pUTF16 = GetUTF16FromANSI(filename); pdecompress = CreateIAPEDecompress(pUTF16, &ret); free(pUTF16); if (!pdecompress || ret != ERROR_SUCCESS) { return DECODER_OPEN_BADLIB; } pd->decompress = (void *)pdecompress; pd->sample_rate = pdecompress->GetInfo(APE_INFO_SAMPLE_RATE); pd->bits_per_sample = pdecompress->GetInfo(APE_INFO_BITS_PER_SAMPLE); pd->bitrate = pdecompress->GetInfo(APE_DECOMPRESS_AVERAGE_BITRATE); pd->channels = pdecompress->GetInfo(APE_INFO_CHANNELS); pd->length_in_ms = pdecompress->GetInfo(APE_DECOMPRESS_LENGTH_MS); pd->block_align = pdecompress->GetInfo(APE_INFO_BLOCK_ALIGN); pd->compression_level = pdecompress->GetInfo(APE_INFO_COMPRESSION_LEVEL); if ((pd->channels != 1) && (pd->channels != 2)) { printf("Sorry, MAC file with %d channels is not supported.\n", pd->channels); return DECODER_OPEN_BADLIB; } if ((pd->bits_per_sample != 8) && (pd->bits_per_sample != 16) && (pd->bits_per_sample != 32)) { printf("Sorry, MAC file with %d bits per sample is not supported.\n", pd->bits_per_sample); return DECODER_OPEN_BADLIB; } pd->swap_bytes = bigendianp(); pd->is_eos = 0; pd->rb = rb_create(pd->channels * sample_size * RB_MAC_SIZE); fdec->fileinfo.channels = pd->channels; fdec->fileinfo.sample_rate = pd->sample_rate; fdec->fileinfo.total_samples = (unsigned long long)(pd->sample_rate / 1000.0f * pd->length_in_ms); fdec->fileinfo.bps = pd->bitrate * 1000; fdec->file_lib = MAC_LIB; strcpy(dec->format_str, "Monkey's Audio"); switch (pd->compression_level) { case COMPRESSION_LEVEL_FAST: sprintf(dec->format_str, "%s (%s)", dec->format_str, _("Compression: Fast")); break; case COMPRESSION_LEVEL_NORMAL: sprintf(dec->format_str, "%s (%s)", dec->format_str, _("Compression: Normal")); break; case COMPRESSION_LEVEL_HIGH: sprintf(dec->format_str, "%s (%s)", dec->format_str, _("Compression: High")); break; case COMPRESSION_LEVEL_EXTRA_HIGH: sprintf(dec->format_str, "%s (%s)", dec->format_str, _("Compression: Extra High")); break; case COMPRESSION_LEVEL_INSANE: sprintf(dec->format_str, "%s (%s)", dec->format_str, _("Compression: Insane")); break; default: printf("Unknown MAC compression level %d\n", pd->compression_level); break; } meta = metadata_new(); meta_ape_send_metadata(meta, fdec); return DECODER_OPEN_SUCCESS; } void mac_decoder_send_metadata(decoder_t * dec) { } void mac_decoder_close(decoder_t * dec) { mac_pdata_t * pd = (mac_pdata_t *)dec->pdata; IAPEDecompress * pdecompress = (IAPEDecompress *)pd->decompress; delete(pdecompress); rb_free(pd->rb); } unsigned int mac_decoder_read(decoder_t * dec, float * dest, int num) { mac_pdata_t * pd = (mac_pdata_t *)dec->pdata; unsigned int numread = 0; int n_avail = 0; while ((rb_read_space(pd->rb) < num * pd->channels * sample_size) && (!pd->is_eos)) { pd->is_eos = decode_mac(dec); } n_avail = rb_read_space(pd->rb) / (pd->channels * sample_size); if (n_avail > num) n_avail = num; rb_read(pd->rb, (char *)dest, n_avail * pd->channels * sample_size); numread = n_avail; return numread; } void mac_decoder_seek(decoder_t * dec, unsigned long long seek_to_pos) { mac_pdata_t * pd = (mac_pdata_t *)dec->pdata; file_decoder_t * fdec = dec->fdec; IAPEDecompress * pdecompress = (IAPEDecompress *)pd->decompress; char flush_dest; pdecompress->Seek(seek_to_pos); fdec->samples_left = fdec->fileinfo.total_samples - seek_to_pos; /* empty mac decoder ringbuffer */ while (rb_read_space(pd->rb)) rb_read(pd->rb, &flush_dest, sizeof(char)); } #else decoder_t * mac_decoder_init(file_decoder_t * fdec) { return NULL; } #endif /* HAVE_MAC */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/decoder/dec_mod.h0000644000175000001440000000410011243310677015050 00000000000000/* -*- linux-c -*- Copyright (C) 2005 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: dec_mod.h 1068 2009-07-24 12:02:30Z peterszilagyi $ */ #ifndef _DEC_MOD_H #define _DEC_MOD_H #ifdef HAVE_MOD #include #ifdef __FreeBSD__ #include #endif /* __FreeBSD__ */ #include #include #endif /* HAVE_MOD */ #include "file_decoder.h" /* Decoding buffer size for libmodplug */ #define MOD_BUFSIZE 8192 /* size of ringbuffer for decoded MOD Audio data (in frames) */ #define RB_MOD_SIZE 262144 #ifdef HAVE_MOD typedef struct _mod_pdata_t { rb_t * rb; ModPlug_Settings mp_settings; ModPlugFile * mpf; int fd; void * fdm; struct stat st; int is_eos; } mod_pdata_t; #endif /* HAVE_MOD */ enum { GZ = 0, BZ2 }; decoder_t * mod_decoder_init(file_decoder_t * fdec); #ifdef HAVE_MOD void mod_decoder_destroy(decoder_t * dec); int is_valid_mod_extension(char * filename); int mod_decoder_open(decoder_t * dec, char * filename); void mod_decoder_send_metadata(decoder_t * dec); void mod_decoder_close(decoder_t * dec); unsigned int mod_decoder_read(decoder_t * dec, float * dest, int num); void mod_decoder_seek(decoder_t * dec, unsigned long long seek_to_pos); #endif /* HAVE_MOD */ #endif /* _DEC_MOD_H */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/decoder/dec_mod.c0000644000175000001440000003262411243310677015057 00000000000000/* -*- linux-c -*- Copyright (C) 2005 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: dec_mod.c 1068 2009-07-24 12:02:30Z peterszilagyi $ */ #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_LIBZ #include #endif /* HAVE_LIBZ */ #ifdef HAVE_LIBBZ2 #include #endif /* HAVE_LIBBZ2 */ #include "../metadata.h" #include "dec_mod.h" extern size_t sample_size; #ifdef HAVE_MOD /* list of accepted file extensions */ char * valid_extensions_mod[] = { "669", "amf", "ams", "dbm", "dmf", "dsm", "far", "it", "j2b", "mdl", "med", "mod", "mt2", "mtm", "okt", "psm", "ptm", "s3m", "stm", "ult", "umx", "xm", #ifdef HAVE_LIBZ "gz", #endif /* HAVE_LIBZ */ #ifdef HAVE_LIBBZ2 "bz2", #endif /* HAVE_LIBBZ2 */ NULL }; #if defined(HAVE_LIBZ) || defined(HAVE_LIBBZ2) char unpacked_filename[PATH_MAX]; char * unpack_file (char *filename, int type) { char *pos, *c; int i, len = 0; char buffer[16384]; #ifdef HAVE_LIBZ gzFile *gz_input_file = NULL; #endif /* HAVE_LIBZ */ #ifdef HAVE_LIBBZ2 BZFILE *bz2_input_file = NULL; #endif /* HAVE_LIBBZ2 */ FILE *output_file; unpacked_filename[0] = '\0'; if ((type == GZ || type == BZ2) && (pos = strrchr(filename, '.')) != NULL) { pos++; if (type == GZ) { if (strcasecmp(pos, "gz") != 0) { return NULL; } } else { if (strcasecmp(pos, "bz2") != 0) { return NULL; } } strncat(unpacked_filename, "/tmp/", PATH_MAX-1); i = 5; /* strlen("/tmp/") */ if ((c = strrchr(filename, '/')) != NULL) { c++; while (c != pos-1) { unpacked_filename[i++] = *c; c++; } } unpacked_filename[i] = '\0'; if (type == GZ) { #ifdef HAVE_LIBZ if ((gz_input_file = gzopen (filename, "r")) == NULL) { return NULL; } #endif /* HAVE_LIBZ */ } else { #ifdef HAVE_LIBBZ2 if ((bz2_input_file = BZ2_bzopen (filename, "r")) == NULL) { return NULL; } #endif /* HAVE_LIBBZ2 */ } if ((output_file = fopen (unpacked_filename, "w")) == NULL) { return NULL; } while (1) { if (type == GZ) { #ifdef HAVE_LIBZ len = gzread(gz_input_file, buffer, sizeof(buffer)); #endif /* HAVE_LIBZ */ } else { #ifdef HAVE_LIBBZ2 len = BZ2_bzread(bz2_input_file, buffer, sizeof(buffer)); #endif /* HAVE_LIBBZ2 */ } if (len < 0) { return NULL; } if (len == 0) break; if ((int)fwrite(buffer, 1, (unsigned)len, output_file) != len) { return NULL; } } if (fclose(output_file)) { return NULL; } if (type == GZ) { #ifdef HAVE_LIBZ if (gzclose(gz_input_file) != Z_OK){ return NULL; } #endif /* HAVE_LIBZ */ } else { #ifdef HAVE_LIBBZ2 BZ2_bzclose(bz2_input_file); #endif /* HAVE_LIBBZ2 */ } return unpacked_filename; } else { return NULL; } } int remove_unpacked_file (void) { if (unpacked_filename[0]) { unlink (unpacked_filename); return 1; } return 0; } #endif /* HAVE_LIBZ && HAVE_LIBBZ2 */ /* return 1 if reached end of stream, 0 else */ int decode_mod(decoder_t * dec) { mod_pdata_t * pd = (mod_pdata_t *)dec->pdata; file_decoder_t * fdec = dec->fdec; int i; long bytes_read; float fbuffer[MOD_BUFSIZE/2]; char buffer[MOD_BUFSIZE]; if ((bytes_read = ModPlug_Read(pd->mpf, buffer, MOD_BUFSIZE)) > 0) { for (i = 0; i < bytes_read/2; i++) { fbuffer[i] = *((short *)(buffer + 2*i)) * fdec->voladj_lin / 32768.f; } rb_write(pd->rb, (char *)fbuffer, bytes_read/2 * sample_size); return 0; } else { return 1; } } decoder_t * mod_decoder_init(file_decoder_t * fdec) { decoder_t * dec = NULL; if ((dec = calloc(1, sizeof(decoder_t))) == NULL) { fprintf(stderr, "dec_mod.c: mod_decoder_new() failed: calloc error\n"); return NULL; } dec->fdec = fdec; if ((dec->pdata = calloc(1, sizeof(mod_pdata_t))) == NULL) { fprintf(stderr, "dec_mod.c: mod_decoder_new() failed: calloc error\n"); return NULL; } dec->init = mod_decoder_init; dec->destroy = mod_decoder_destroy; dec->open = mod_decoder_open; dec->send_metadata = mod_decoder_send_metadata; dec->close = mod_decoder_close; dec->read = mod_decoder_read; dec->seek = mod_decoder_seek; return dec; } void mod_decoder_destroy(decoder_t * dec) { free(dec->pdata); free(dec); } int is_valid_mod_extension(char * filename) { return is_valid_extension(valid_extensions_mod, filename, 1); } void mod_name_filter(char *str) { char buffer[MAXLEN]; int n, k, f, len; strncpy(buffer, str, MAXLEN-1); k = f = n = 0; len = strlen(buffer); while (buffer[n] == ' ' || buffer[n] == '\t' || buffer[n] == '_' || buffer[n] == '.') { n++; } for(; n < len; n++) { if (isprint(buffer[n])) { if (buffer[n] == '_' || buffer[n] == '.') { buffer[n] = ' '; } str[k++] = buffer[n]; f = 1; } } if (f) { str[k] = '\0'; } } void mod_filename_filter(char *str, char **valid_extensions) { char buffer[MAXLEN]; char *pos; int i; strncpy(buffer, str, MAXLEN-1); if ((pos = strrchr(buffer, '/')) != NULL) { pos++; i = 0; while(pos[i]) { str[i] = pos[i]; i++; } str[i] = '\0'; } if ((pos = strrchr(str, '.')) != NULL) { if (strcasecmp(pos+1, "gz") == 0 || strcasecmp (pos+1, "bz2") == 0) { *pos = '\0'; } } if ((pos = strrchr(str, '.')) != NULL) { i = 0; while (valid_extensions[i] != NULL) { if (strcasecmp(pos+1, valid_extensions[i]) == 0) { *pos = '\0'; } ++i; } } strncpy(buffer, str, MAXLEN-1); if ((pos = strchr(buffer, '.')) != NULL) { *pos = '\0'; i = 0; while (valid_extensions[i] != NULL) { if (strcasecmp(buffer, valid_extensions[i]) == 0) { pos++; i = 0; while (pos[i] != '\0') { str[i] = pos[i]; i++; } str[i] = '\0'; break; } ++i; } } } void mod_send_metadata(decoder_t * dec) { mod_pdata_t * pd = (mod_pdata_t *)dec->pdata; file_decoder_t * fdec = dec->fdec; metadata_t * meta = metadata_new(); meta_frame_t * frame = meta_frame_new(); mod_info mi; if (meta == NULL) { fprintf(stderr, "mod_send_metadata: metadata_new() failed\n"); return; } if (frame == NULL) { fprintf(stderr, "mod_send_metadata: meta_frame_new() failed\n"); return; } memset(&mi, 0x00, sizeof(mod_info)); strncpy(mi.title, ModPlug_GetName(pd->mpf), MAXLEN-1); mod_name_filter(mi.title); if (!strlen(mi.title)) { strncpy(mi.title, fdec->filename, MAXLEN-1); mod_filename_filter(mi.title, valid_extensions_mod); mod_name_filter(mi.title); } mi.active = 1; #ifdef HAVE_MOD_INFO mi.type = ModPlug_GetModuleType(pd->mpf); mi.samples = ModPlug_NumSamples(pd->mpf); mi.instruments = ModPlug_NumInstruments(pd->mpf); mi.patterns = ModPlug_NumPatterns(pd->mpf); mi.channels = ModPlug_NumChannels(pd->mpf); #endif /* HAVE_MOD_INFO */ metadata_add_frame(meta, frame); frame->tag = META_TAG_MODINFO; frame->type = META_FIELD_MODINFO; frame->data = calloc(sizeof(mod_info), 1); frame->length = sizeof(mod_info); if (frame->data == NULL) { fprintf(stderr, "mod_send_metadata: calloc() error\n"); metadata_free(meta); return; } memcpy(frame->data, &mi, sizeof(mod_info)); meta->fdec = fdec; fdec->meta = meta; } int mod_decoder_open(decoder_t * dec, char * mod_filename) { char *filename = NULL; mod_pdata_t * pd = (mod_pdata_t *)dec->pdata; file_decoder_t * fdec = dec->fdec; #ifdef HAVE_LIBZ filename = unpack_file(mod_filename, GZ); #endif /* HAVE_LIBZ */ #ifdef HAVE_LIBBZ2 if (filename == NULL) { filename = unpack_file(mod_filename, BZ2); } #endif /* HAVE_LIBBZ2 */ if (filename == NULL) { filename = mod_filename; } if (!is_valid_mod_extension(filename)) { return DECODER_OPEN_BADLIB; } if ((pd->fd = open(filename, O_RDONLY)) == -1) { fprintf(stderr, "mod_decoder_open: nonexistent or non-accessible file: %s\n", filename); return DECODER_OPEN_FERROR; } if (fstat(pd->fd, &(pd->st)) == -1 || pd->st.st_size == 0) { fprintf(stderr, "mod_decoder_open: fstat() error or zero-length file: %s\n", filename); close(pd->fd); return DECODER_OPEN_FERROR; } pd->fdm = mmap(0, pd->st.st_size, PROT_READ, MAP_SHARED, pd->fd, 0); if (pd->fdm == MAP_FAILED) { fprintf(stderr, "mod_decoder_open: mmap() failed %s\n", filename); close(pd->fd); return DECODER_OPEN_FERROR; } if ((pd->mpf = ModPlug_Load(pd->fdm, pd->st.st_size)) == NULL) { if (munmap(pd->fdm, pd->st.st_size) == -1) fprintf(stderr, "Error while munmap()'ing MOD Audio file mapping\n"); close(pd->fd); return DECODER_OPEN_BADLIB; } if (pd->st.st_size * 8000.0f / ModPlug_GetLength(pd->mpf) >= 1000000.0f) { fprintf(stderr, "mod_decoder_open: MOD bitrate greater than 1 Mbit/s, " "very likely not a MOD file: %s\n", filename); ModPlug_Unload(pd->mpf); if (munmap(pd->fdm, pd->st.st_size) == -1) fprintf(stderr, "Error while munmap()'ing MOD Audio file mapping\n"); close(pd->fd); return DECODER_OPEN_BADLIB; } /* set libmodplug decoder parameters */ pd->mp_settings.mFlags = MODPLUG_ENABLE_OVERSAMPLING | MODPLUG_ENABLE_NOISE_REDUCTION; pd->mp_settings.mChannels = 2; pd->mp_settings.mBits = 16; pd->mp_settings.mFrequency = 44100; pd->mp_settings.mResamplingMode = MODPLUG_RESAMPLE_FIR; pd->mp_settings.mReverbDepth = 100; pd->mp_settings.mReverbDelay = 100; pd->mp_settings.mBassAmount = 100; pd->mp_settings.mBassRange = 100; pd->mp_settings.mSurroundDepth = 100; pd->mp_settings.mSurroundDelay = 40; pd->mp_settings.mLoopCount = 0; ModPlug_SetSettings(&(pd->mp_settings)); pd->is_eos = 0; pd->rb = rb_create(pd->mp_settings.mChannels * sample_size * RB_MOD_SIZE); fdec->fileinfo.channels = pd->mp_settings.mChannels; fdec->fileinfo.sample_rate = pd->mp_settings.mFrequency; fdec->file_lib = MOD_LIB; strcpy(dec->format_str, "MOD Audio"); fdec->fileinfo.total_samples = ModPlug_GetLength(pd->mpf) / 1000.0f * pd->mp_settings.mFrequency; fdec->fileinfo.bps = pd->st.st_size * 8000.0f / ModPlug_GetLength(pd->mpf); mod_send_metadata(dec); return DECODER_OPEN_SUCCESS; } void mod_decoder_send_metadata(decoder_t * dec) { file_decoder_t* fdec = dec->fdec; if (fdec->meta != NULL && fdec->meta_cb != NULL) { fdec->meta_cb(fdec->meta, fdec->meta_cbdata); } } void mod_decoder_close(decoder_t * dec) { mod_pdata_t * pd = (mod_pdata_t *)dec->pdata; ModPlug_Unload(pd->mpf); #if defined(HAVE_LIBZ) || defined(HAVE_LIBBZ2) remove_unpacked_file(); #endif /* HAVE_LIBZ, HAVE_LIBBZ2 */ if (munmap(pd->fdm, pd->st.st_size) == -1) fprintf(stderr, "Error while munmap()'ing MOD Audio file mapping\n"); close(pd->fd); rb_free(pd->rb); } unsigned int mod_decoder_read(decoder_t * dec, float * dest, int num) { mod_pdata_t * pd = (mod_pdata_t *)dec->pdata; unsigned int numread = 0; unsigned int n_avail = 0; while ((rb_read_space(pd->rb) < num * pd->mp_settings.mChannels * sample_size) && (!pd->is_eos)) { pd->is_eos = decode_mod(dec); } n_avail = rb_read_space(pd->rb) / (pd->mp_settings.mChannels * sample_size); if (n_avail > num) n_avail = num; rb_read(pd->rb, (char *)dest, n_avail * pd->mp_settings.mChannels * sample_size); numread = n_avail; return numread; } void mod_decoder_seek(decoder_t * dec, unsigned long long seek_to_pos) { mod_pdata_t * pd = (mod_pdata_t *)dec->pdata; file_decoder_t * fdec = dec->fdec; char flush_dest; if (seek_to_pos == fdec->fileinfo.total_samples) { --seek_to_pos; } ModPlug_Seek(pd->mpf, (double)seek_to_pos / pd->mp_settings.mFrequency * 1000.0f); fdec->samples_left = fdec->fileinfo.total_samples - seek_to_pos; /* empty mod decoder ringbuffer */ while (rb_read_space(pd->rb)) rb_read(pd->rb, &flush_dest, sizeof(char)); } #else decoder_t * mod_decoder_init(file_decoder_t * fdec) { return NULL; } #endif /* HAVE_MOD */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/decoder/dec_mpc.h0000644000175000001440000000415711253161434015060 00000000000000/* -*- linux-c -*- Copyright (C) 2005 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: dec_mpc.h 1079 2009-09-04 19:40:39Z tszilagyi $ */ #ifndef _DEC_MPC_H #define _DEC_MPC_H #ifdef HAVE_MPC #ifdef MPC_OLD_API #include #else #include #endif /* MPC_OLD_API */ #endif /* HAVE_MPC */ #include "file_decoder.h" /* Decoding buffer size for musepack */ #define MPC_BUFSIZE 8192 /* size of ringbuffer for decoded Musepack audio data (in frames) */ #define RB_MPC_SIZE 262144 #ifdef HAVE_MPC typedef struct _mpc_pdata_t { rb_t * rb; FILE * mpc_file; long int size; int seekable; int status; int is_eos; #ifdef MPC_OLD_API mpc_decoder mpc_d; mpc_reader_file mpc_r_f; #else mpc_demux * mpc_d; mpc_reader mpc_r_f; #endif /* MPC_OLD_API */ mpc_streaminfo mpc_i; } mpc_pdata_t; #endif /* HAVE_MPC */ decoder_t * mpc_decoder_init_func(file_decoder_t * fdec); #ifdef HAVE_MPC void mpc_decoder_destroy(decoder_t * dec); int mpc_decoder_open(decoder_t * dec, char * filename); void mpc_decoder_send_metadata(decoder_t * dec); void mpc_decoder_close(decoder_t * dec); unsigned int mpc_decoder_read(decoder_t * dec, float * dest, int num); void mpc_decoder_seek(decoder_t * dec, unsigned long long seek_to_pos); #endif /* HAVE_MPC */ #endif /* _DEC_MPC_H */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/decoder/dec_mpc.c0000644000175000001440000002063611253161435015054 00000000000000/* -*- linux-c -*- Copyright (C) 2005 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: dec_mpc.c 1079 2009-09-04 19:40:39Z tszilagyi $ */ #include #include #include #include #include "../i18n.h" #include "../metadata_ape.h" #include "dec_mpc.h" extern size_t sample_size; #ifdef HAVE_MPC /* return 1 if reached end of stream, 0 else */ int decode_mpc(decoder_t * dec) { mpc_pdata_t * pd = (mpc_pdata_t *)dec->pdata; file_decoder_t * fdec = dec->fdec; int n; float fval; MPC_SAMPLE_FORMAT buffer[MPC_DECODER_BUFFER_LENGTH]; #ifdef MPC_OLD_API pd->status = mpc_decoder_decode(&pd->mpc_d, buffer, NULL, NULL); if (pd->status == (unsigned)(-1)) { fprintf(stderr, "decode_mpc: mpc decoder reported an error\n"); return 1; /* ignore the rest of the stream */ } else if (pd->status == 0) { return 1; /* end of stream */ } #else mpc_frame_info frame; mpc_status err; frame.buffer = buffer; err = mpc_demux_decode(pd->mpc_d, &frame); if (err != MPC_STATUS_OK) { fprintf(stderr, "decode_mpc: mpc decoder reported an error\n"); return 1; /* ignore the rest of the stream */ } else if (frame.bits == -1) { return 1; /* end of stream */ } pd->status = frame.samples; #endif /* MPC_OLD_API */ for (n = 0; n < pd->status * pd->mpc_i.channels; n++) { #ifdef MPC_FIXED_POINT fval = buffer[n] / (double)MPC_FIXED_POINT_SCALE * fdec->voladj_lin; #else fval = buffer[n] * fdec->voladj_lin; #endif /* MPC_FIXED_POINT */ if (fval < -1.0f) { fval = -1.0f; } else if (fval > 1.0f) { fval = 1.0f; } rb_write(pd->rb, (char *)&fval, sample_size); } return 0; } decoder_t * mpc_decoder_init_func(file_decoder_t * fdec) { decoder_t * dec = NULL; if ((dec = calloc(1, sizeof(decoder_t))) == NULL) { fprintf(stderr, "dec_mpc.c: mpc_decoder_new() failed: calloc error\n"); return NULL; } dec->fdec = fdec; if ((dec->pdata = calloc(1, sizeof(mpc_pdata_t))) == NULL) { fprintf(stderr, "dec_mpc.c: mpc_decoder_new() failed: calloc error\n"); return NULL; } dec->init = mpc_decoder_init_func; dec->destroy = mpc_decoder_destroy; dec->open = mpc_decoder_open; dec->send_metadata = mpc_decoder_send_metadata; dec->close = mpc_decoder_close; dec->read = mpc_decoder_read; dec->seek = mpc_decoder_seek; return dec; } void mpc_decoder_destroy(decoder_t * dec) { free(dec->pdata); free(dec); } void mpc_add_rg_frame(metadata_t * meta, int type, float fval) { meta_frame_t * frame = meta_frame_new(); char * str; if (frame == NULL) { return; } frame->tag = META_TAG_MPC_RGDATA; frame->type = type; frame->flags = META_FIELD_UNIQUE | META_FIELD_MANDATORY; meta_get_fieldname(type, &str); frame->field_name = strdup(str); frame->float_val = fval; metadata_add_frame(meta, frame); } void mpc_add_rg_meta(metadata_t * meta, mpc_streaminfo * si) { float track_gain = si->gain_title / 100.0; float album_gain = si->gain_album / 100.0; float track_peak = si->peak_title / 32768.0; float album_peak = si->peak_album / 32768.0; if (meta == NULL) { return; } /* XXX TODO FIXME: * This is commented just yet so as not to offer this tag * for creation since we don't support saving it anyway. */ /* meta->valid_tags |= META_TAG_MPC_RGDATA; */ if ((track_gain == 0.0f) && (album_gain == 0.0f) && (track_peak == 0.0f) && (album_peak == 0.0f)) { return; } mpc_add_rg_frame(meta, META_FIELD_RG_TRACK_GAIN, track_gain); mpc_add_rg_frame(meta, META_FIELD_RG_ALBUM_GAIN, album_gain); mpc_add_rg_frame(meta, META_FIELD_RG_TRACK_PEAK, track_peak); mpc_add_rg_frame(meta, META_FIELD_RG_ALBUM_PEAK, album_peak); } int mpc_decoder_open(decoder_t * dec, char * filename) { mpc_pdata_t * pd = (mpc_pdata_t *)dec->pdata; file_decoder_t * fdec = dec->fdec; metadata_t * meta; if ((pd->mpc_file = fopen(filename, "rb")) == NULL) { fprintf(stderr, "mpc_decoder_open: fopen() failed for Musepack file\n"); return DECODER_OPEN_FERROR; } pd->seekable = 1; fseek(pd->mpc_file, 0, SEEK_END); pd->size = ftell(pd->mpc_file); fseek(pd->mpc_file, 0, SEEK_SET); #ifdef MPC_OLD_API mpc_reader_setup_file_reader(&pd->mpc_r_f, pd->mpc_file); mpc_streaminfo_init(&pd->mpc_i); if (mpc_streaminfo_read(&pd->mpc_i, &pd->mpc_r_f.reader) != ERROR_CODE_OK) { fclose(pd->mpc_file); return DECODER_OPEN_BADLIB; } mpc_decoder_setup(&pd->mpc_d, &pd->mpc_r_f.reader); if (!mpc_decoder_initialize(&pd->mpc_d, &pd->mpc_i)) { fclose(pd->mpc_file); return DECODER_OPEN_BADLIB; } #else mpc_reader_init_stdio_stream(&pd->mpc_r_f, pd->mpc_file); pd->mpc_d = mpc_demux_init(&pd->mpc_r_f); if (!pd->mpc_d) { fclose(pd->mpc_file); return DECODER_OPEN_BADLIB; } mpc_demux_get_info(pd->mpc_d, &pd->mpc_i); #endif /* MPC_OLD_API */ pd->is_eos = 0; pd->rb = rb_create(pd->mpc_i.channels * sample_size * RB_MPC_SIZE); fdec->fileinfo.channels = pd->mpc_i.channels; fdec->fileinfo.sample_rate = pd->mpc_i.sample_freq; fdec->fileinfo.total_samples = mpc_streaminfo_get_length_samples(&pd->mpc_i); fdec->fileinfo.bps = pd->mpc_i.average_bitrate; fdec->file_lib = MPC_LIB; strcpy(dec->format_str, "Musepack"); #ifdef MPC_OLD_API switch (pd->mpc_i.profile) { #else switch ((int) pd->mpc_i.profile) { #endif /* MPC_OLD_API */ case 7: sprintf(dec->format_str, "%s (%s)", dec->format_str, _("Profile: Telephone")); break; case 8: sprintf(dec->format_str, "%s (%s)", dec->format_str, _("Profile: Thumb")); break; case 9: sprintf(dec->format_str, "%s (%s)", dec->format_str, _("Profile: Radio")); break; case 10: sprintf(dec->format_str, "%s (%s)", dec->format_str, _("Profile: Standard")); break; case 11: sprintf(dec->format_str, "%s (%s)", dec->format_str, _("Profile: Xtreme")); break; case 12: sprintf(dec->format_str, "%s (%s)", dec->format_str, _("Profile: Insane")); break; case 13: sprintf(dec->format_str, "%s (%s)", dec->format_str, _("Profile: Braindead")); break; } meta = metadata_new(); mpc_add_rg_meta(meta, &pd->mpc_i); meta_ape_send_metadata(meta, fdec); return DECODER_OPEN_SUCCESS; } void mpc_decoder_send_metadata(decoder_t * dec) { } void mpc_decoder_close(decoder_t * dec) { mpc_pdata_t * pd = (mpc_pdata_t *)dec->pdata; rb_free(pd->rb); fclose(pd->mpc_file); } unsigned int mpc_decoder_read(decoder_t * dec, float * dest, int num) { mpc_pdata_t * pd = (mpc_pdata_t *)dec->pdata; unsigned int numread = 0; unsigned int n_avail = 0; while ((rb_read_space(pd->rb) < num * pd->mpc_i.channels * sample_size) && (!pd->is_eos)) { pd->is_eos = decode_mpc(dec); } n_avail = rb_read_space(pd->rb) / (pd->mpc_i.channels * sample_size); if (n_avail > num) n_avail = num; rb_read(pd->rb, (char *)dest, n_avail * pd->mpc_i.channels * sample_size); numread = n_avail; return numread; } void mpc_decoder_seek(decoder_t * dec, unsigned long long seek_to_pos) { mpc_pdata_t * pd = (mpc_pdata_t *)dec->pdata; file_decoder_t * fdec = dec->fdec; char flush_dest; #ifdef MPC_OLD_API if (mpc_decoder_seek_sample(&pd->mpc_d, seek_to_pos)) { #else if (mpc_demux_seek_sample(pd->mpc_d, seek_to_pos) == MPC_STATUS_OK) { #endif /* MPC_OLD_API */ fdec->samples_left = fdec->fileinfo.total_samples - seek_to_pos; /* empty musepack decoder ringbuffer */ while (rb_read_space(pd->rb)) rb_read(pd->rb, &flush_dest, sizeof(char)); } else { fprintf(stderr, "mpc_decoder_seek: warning: mpc_decoder_seek_sample() failed\n"); } } #else decoder_t * mpc_decoder_init_func(file_decoder_t * fdec) { return NULL; } #endif /* HAVE_MPC */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/decoder/dec_mpeg.h0000644000175000001440000001165211243310677015233 00000000000000/* -*- linux-c -*- Copyright (C) 2005 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: dec_mpeg.h 1068 2009-07-24 12:02:30Z peterszilagyi $ */ #ifndef _DEC_MPEG_H #define _DEC_MPEG_H #ifdef HAVE_MPEG #include #include #endif /* HAVE_MPEG */ #include "../common.h" #include "../httpc.h" #include "file_decoder.h" /* size of ringbuffer for decoded MPEG Audio data (in frames) */ #define RB_MAD_SIZE 262144 /* for stream (non-mmap) decoding */ #define MPEG_INBUF_SIZE (5*8192) #ifdef HAVE_MPEG #define MPEG_VERSION1 0 #define MPEG_VERSION2 1 #define MPEG_VERSION2_5 2 /* MPEG Audio subformats */ #define MPEG_LAYER_I 0x001 #define MPEG_LAYER_II 0x002 #define MPEG_LAYER_III 0x004 #define MPEG_LAYER_MASK 0x007 #define MPEG_MODE_SINGLE 0x010 #define MPEG_MODE_DUAL 0x020 #define MPEG_MODE_JOINT 0x040 #define MPEG_MODE_STEREO 0x080 #define MPEG_MODE_MASK 0x0F0 #define MPEG_EMPH_NONE 0x100 #define MPEG_EMPH_5015 0x200 #define MPEG_EMPH_J_17 0x400 #define MPEG_EMPH_RES 0x800 #define MPEG_EMPH_MASK 0xF00 typedef struct { /* Standard MP3 frame header fields */ int version; int layer; int protection; int bitrate; long frequency; int padding; int channel_mode; int mode_extension; int emphasis; int frame_size; /* Frame size in bytes */ int frame_samples; /* Samples per frame */ int ft_num; /* Numerator of frametime in milliseconds */ int ft_den; /* Denominator of frametime in milliseconds */ int is_vbr; /* True if the file is VBR */ int has_toc; /* True if there is a VBR header in the file */ int is_xing_vbr; /* True if the VBR header is of Xing type */ int is_vbri_vbr; /* True if the VBR header is of VBRI type */ unsigned char toc[100]; unsigned long frame_count; /* Number of frames in the file (if VBR) */ unsigned long byte_count; /* File size in bytes */ unsigned long file_time; /* Length of the whole file in milliseconds */ unsigned long vbr_header_pos; int enc_delay; /* Encoder delay, fetched from LAME header */ int enc_padding; /* Padded samples added to last frame. LAME header */ /* first valid(!) frame */ unsigned long start_byteoffset; } mp3info_t; /* Xing header information */ #define VBR_FRAMES_FLAG 0x01 #define VBR_BYTES_FLAG 0x02 #define VBR_TOC_FLAG 0x04 #define VBR_QUALITY_FLAG 0x08 #define MAX_XING_HEADER_SIZE 576 unsigned long find_next_frame(int fd, long *offset, long max_offset, unsigned long last_header, int is_ubr_allowed); typedef struct { int frame; /* number of mpeg frame */ unsigned long long sample; /* number of audio samples since beginning of file */ unsigned long offset; /* byte offset from beginning of file */ } mpeg_seek_table_t; typedef struct _mpeg_pdata_t { struct mad_decoder mpeg_decoder; rb_t * rb; FILE * mpeg_file; int channels; int SR; unsigned bitrate; int error; int is_eos; struct stat mpeg_stat; long long int filesize; long skip_bytes; long delay_frames; int fd; void * fdm; unsigned long total_samples_est; int mpeg_subformat; /* used as v_minor */ mp3info_t mp3info; int seek_table_built; AQUALUNG_THREAD_DECLARE(seek_builder_id) int builder_thread_running; mpeg_seek_table_t seek_table[100]; unsigned long frame_counter; long last_frames[2]; /* [0] is the last frame's byte offset, [1] the last-but-one */ /* for stream decoding */ http_session_t * session; unsigned char * inbuf; struct mad_stream mpeg_stream; struct mad_frame mpeg_frame; struct mad_synth mpeg_synth; } mpeg_pdata_t; #endif /* HAVE_MPEG */ decoder_t * mpeg_decoder_init(file_decoder_t * fdec); #ifdef HAVE_MPEG void mpeg_decoder_destroy(decoder_t * dec); int mpeg_decoder_open(decoder_t * dec, char * filename); void mpeg_decoder_send_metadata(decoder_t * dec); int mpeg_stream_decoder_open(decoder_t * dec, http_session_t * session); void mpeg_decoder_close(decoder_t * dec); unsigned int mpeg_decoder_read(decoder_t * dec, float * dest, int num); void mpeg_decoder_seek(decoder_t * dec, unsigned long long seek_to_pos); #endif /* HAVE_MPEG */ #endif /* _DEC_MPEG_H */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/decoder/dec_mpeg.c0000644000175000001440000012375211243310677015233 00000000000000/* -*- linux-c -*- Copyright (C) 2005 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: dec_mpeg.c 1068 2009-07-24 12:02:30Z peterszilagyi $ */ #include #include #include #include #include #include #include #include #include #ifdef _WIN32 #include #else #include #endif /* _WIN32 */ #include "../i18n.h" #ifdef HAVE_MOD #include "dec_mod.h" #endif /* HAVE_MOD */ #include "../metadata.h" #include "../metadata_ape.h" #include "../metadata_id3v1.h" #include "../metadata_id3v2.h" #include "dec_mpeg.h" extern size_t sample_size; #ifdef HAVE_MPEG /* Uncomment this to get debug printouts */ /* #define MPEG_DEBUG */ #define BYTES2INT(b1,b2,b3,b4) (((long)(b1 & 0xFF) << (3*8)) | \ ((long)(b2 & 0xFF) << (2*8)) | \ ((long)(b3 & 0xFF) << (1*8)) | \ ((long)(b4 & 0xFF) << (0*8))) #define SYNC_MASK (0x7ffL << 21) #define VERSION_MASK (3L << 19) #define LAYER_MASK (3L << 17) #define PROTECTION_MASK (1L << 16) #define BITRATE_MASK (0xfL << 12) #define SAMPLERATE_MASK (3L << 10) #define PADDING_MASK (1L << 9) #define PRIVATE_MASK (1L << 8) #define CHANNELMODE_MASK (3L << 6) #define MODE_EXT_MASK (3L << 4) #define COPYRIGHT_MASK (1L << 3) #define ORIGINAL_MASK (1L << 2) #define EMPHASIS_MASK 3L /* list of accepted file extensions */ char * valid_extensions_mpeg[] = { "mp3", "mpa", "mpga", "mpega", "abs", "mp2", "mp2a", "mpa2", "mp1", NULL }; /* MPEG Version table, sorted by version index */ static const signed char version_table[4] = { MPEG_VERSION2_5, -1, MPEG_VERSION2, MPEG_VERSION1 }; /* Bitrate table for mpeg audio, indexed by row index and birate index */ static const short bitrates[5][16] = { {0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,0}, /* V1 L1 */ {0,32,48,56, 64, 80, 96,112,128,160,192,224,256,320,384,0}, /* V1 L2 */ {0,32,40,48, 56, 64, 80, 96,112,128,160,192,224,256,320,0}, /* V1 L3 */ {0,32,48,56, 64, 80, 96,112,128,144,160,176,192,224,256,0}, /* V2 L1 */ {0, 8,16,24, 32, 40, 48, 56, 64, 80, 96,112,128,144,160,0} /* V2 L2+L3 */ }; /* Bitrate pointer table, indexed by version and layer */ static const short *bitrate_table[3][3] = { {bitrates[0], bitrates[1], bitrates[2]}, {bitrates[3], bitrates[4], bitrates[4]}, {bitrates[3], bitrates[4], bitrates[4]} }; /* Sampling frequency table, indexed by version and frequency index */ static const long freq_table[3][3] = { {44100, 48000, 32000}, /* MPEG Version 1 */ {22050, 24000, 16000}, /* MPEG version 2 */ {11025, 12000, 8000}, /* MPEG version 2.5 */ }; /* check if 'head' is a valid mp3 frame header */ static int is_mp3frameheader(unsigned long head, int is_ubr_allowed) { if ((head & SYNC_MASK) != (unsigned long)SYNC_MASK) /* bad sync? */ return 0; if ((head & VERSION_MASK) == (1L << 19)) /* bad version? */ return 0; if (!(head & LAYER_MASK)) /* no layer? */ return 0; if ((head & BITRATE_MASK) == BITRATE_MASK) /* bad bitrate? */ return 0; if ((head & BITRATE_MASK) == 0 && !is_ubr_allowed) /* no bitrate, no UBR */ return 0; if ((head & SAMPLERATE_MASK) == SAMPLERATE_MASK) /* bad sample rate? */ return 0; return 1; } static int mp3headerinfo(mp3info_t *info, unsigned long header) { int bitindex, freqindex; /* MPEG Audio Version */ info->version = version_table[(header & VERSION_MASK) >> 19]; if (info->version < 0) return 0; /* Layer */ info->layer = 3 - ((header & LAYER_MASK) >> 17); if (info->layer == 3) return 0; info->protection = (header & PROTECTION_MASK) ? 1 : 0; /* Bitrate */ bitindex = (header & BITRATE_MASK) >> 12; info->bitrate = bitrate_table[info->version][info->layer][bitindex]; /* Sampling frequency */ freqindex = (header & SAMPLERATE_MASK) >> 10; if (freqindex == 3) return 0; info->frequency = freq_table[info->version][freqindex]; info->padding = (header & PADDING_MASK) ? 1 : 0; /* Calculate number of bytes, calculation depends on layer */ if (info->layer == 0) { info->frame_samples = 384; if (info->bitrate == 0) { info->frame_size = 0; } else { info->frame_size = (12000 * info->bitrate / info->frequency + info->padding) * 4; } } else { if ((info->version > MPEG_VERSION1) && (info->layer == 2)) { info->frame_samples = 576; } else { info->frame_samples = 1152; } if (info->bitrate == 0) { info->frame_size = 0; } else { info->frame_size = (1000/8) * info->frame_samples * info->bitrate / info->frequency + info->padding; } } /* Frametime fraction calculation. This fraction is reduced as far as possible. */ if (freqindex != 0) { /* 48/32/24/16/12/8 kHz */ /* integer number of milliseconds, denominator == 1 */ info->ft_num = 1000 * info->frame_samples / info->frequency; info->ft_den = 1; } else { /* 44.1/22.05/11.025 kHz */ if (info->layer == 0) { info->ft_num = 147000 * 384 / info->frequency; info->ft_den = 147; } else { info->ft_num = 49000 * info->frame_samples / info->frequency; info->ft_den = 49; } } info->channel_mode = (header & CHANNELMODE_MASK) >> 6; info->mode_extension = (header & MODE_EXT_MASK) >> 4; info->emphasis = header & EMPHASIS_MASK; #ifdef MPEG_DEBUG /* printf( "Header: %08x, Ver %d, lay %d, bitr %d, freq %ld, " "chmode %d, mode_ext %d, emph %d, bytes: %d time: %d/%d\n", header, info->version, info->layer+1, info->bitrate, info->frequency, info->channel_mode, info->mode_extension, info->emphasis, info->frame_size, info->ft_num, info->ft_den); */ #endif /* MPEG_DEBUG */ return 1; } static unsigned long __find_next_frame(int fd, long *offset, long max_offset, unsigned long last_header, int(*getfunc)(int fd, unsigned char *c), int is_ubr_allowed) { unsigned long header=0; unsigned char tmp; int i; long pos = 0; /* We remember the last header we found, to use as a template to see if the header we find has the same frequency, layer etc */ last_header &= 0xffff0c00; /* Fill up header with first 24 bits */ for(i = 0; i < 3; i++) { header <<= 8; if(!getfunc(fd, &tmp)) return 0; header |= tmp; pos++; } do { header <<= 8; if(!getfunc(fd, &tmp)) return 0; header |= tmp; pos++; if (max_offset > 0 && pos > max_offset) return 0; } while(!is_mp3frameheader(header, is_ubr_allowed) || (last_header?((header & 0xffff0c00) != last_header):0)); *offset = pos - 4; #ifdef MPEG_DEBUG /* if(*offset) printf("Warning: skipping %d bytes of garbage\n", *offset); */ #endif /* MPEG_DEBUG */ return header; } static int fileread(int fd, unsigned char *c) { return read(fd, c, 1); } unsigned long find_next_frame(int fd, long *offset, long max_offset, unsigned long last_header, int is_ubr_allowed) { return __find_next_frame(fd, offset, max_offset, last_header, fileread, is_ubr_allowed); } /* compare two headers according to version, layer, frequency, channel_mode */ int vlfc_cmp(mp3info_t *info1, mp3info_t *info2) { if (info1->version != info2->version) return 0; if (info1->layer != info2->layer) return 0; if (info1->frequency != info2->frequency) return 0; if (info1->channel_mode != info2->channel_mode) return 0; return 1; } int mpeg_write_metadata(file_decoder_t * fdec, metadata_t * meta) { int ret; /* write ID3v1 */ if (metadata_get_frame_by_tag(meta, META_TAG_ID3v1, NULL) != NULL) { unsigned char id3v1[128]; ret = metadata_to_id3v1(meta, id3v1); if (ret != META_ERROR_NONE) { return ret; } ret = meta_id3v1_rewrite(fdec->filename, id3v1); if (ret != META_ERROR_NONE) { return ret; } } else { ret = meta_id3v1_delete(fdec->filename); if (ret != META_ERROR_NONE) { return ret; } } /* write ID3v2 */ if (metadata_get_frame_by_tag(meta, META_TAG_ID3v2, NULL) != NULL) { unsigned char * buf; int length; int ret = metadata_to_id3v2(meta, &buf, &length); if (ret != META_ERROR_NONE) { return ret; } ret = meta_id3v2_rewrite(fdec->filename, &buf, &length); if (ret != META_ERROR_NONE) { free(buf); return ret; } free(buf); } else { ret = meta_id3v2_delete(fdec->filename); if (ret != META_ERROR_NONE) { return ret; } } /* write APE */ ret = meta_ape_write_metadata(fdec, meta); if (ret != META_ERROR_NONE) { return ret; } return META_ERROR_NONE; } void mpeg_send_metadata(file_decoder_t * fdec, int fd) { metadata_t * meta; unsigned char id3v1[128]; unsigned char * id3v2; unsigned long file_size; unsigned char buffer[12]; u_int32_t id3v2_length = 0; ape_tag_t tag; meta = metadata_new(); if (meta == NULL) { return; } /* read ID3v1 */ file_size = lseek(fd, -128, SEEK_END) + 128; if (read(fd, id3v1, 128) == 128) { metadata_from_id3v1(meta, id3v1); } /* read ID3v2 */ lseek(fd, 0L, SEEK_SET); if (read(fd, buffer, 10) == 10) { if ((buffer[0] != 'I') || (buffer[1] != 'D') || (buffer[2] != '3')) { lseek(fd, 0L, SEEK_SET); } else { id3v2_length = meta_id3v2_read_synchsafe_int(buffer+6); id3v2_length += 10; /* add 10 byte header */ #ifdef MPEG_DEBUG printf("id3v2_length = %ld\n", id3v2_length); #endif /* MPEG_DEBUG */ if (id3v2_length > file_size) { fprintf(stderr, "error: ID3v2 tag length greater than file length\n"); return; } id3v2 = malloc(id3v2_length); if (id3v2 == NULL) { fprintf(stderr, "mpeg_send_metadata: malloc error\n"); return; } lseek(fd, 0L, SEEK_SET); if (read(fd, id3v2, id3v2_length) != id3v2_length) { fprintf(stderr, "mpeg_send_metadata: error reading ID3v2 tag\n"); return; } metadata_from_id3v2(meta, id3v2, id3v2_length); free(id3v2); lseek(fd, id3v2_length, SEEK_SET); } } /* read APE */ memset(&tag, 0x00, sizeof(ape_tag_t)); if (meta_ape_parse(fdec->filename, &tag)) { metadata_from_ape_tag(meta, &tag); meta_ape_free(&tag); } /* setup and send metablock */ meta->valid_tags = META_TAG_APE | META_TAG_ID3v1 | META_TAG_ID3v2; if (access(fdec->filename, R_OK | W_OK) == 0) { meta->writable = 1; fdec->meta_write = mpeg_write_metadata; } else { meta->writable = 0; } meta->fdec = fdec; fdec->meta = meta; } int get_mp3file_info(decoder_t * dec) { file_decoder_t * fdec = dec->fdec; mpeg_pdata_t * pd = (mpeg_pdata_t *)dec->pdata; int fd = pd->fd; mp3info_t * info = &pd->mp3info; int vsn_counters[4]; int layer_counters[3]; int freq_counters[7]; int chmode_counters[4]; long offset; unsigned long header = 0; unsigned char frame[1800]; unsigned char *vbrheader; int is_ubr_allowed = 1; long bytecount = 0; int num_offsets; int frames_per_entry; int i; int j; long tmp; int ret; begin_info: for (i = 0; i < 3; i++) { vsn_counters[i] = 0; layer_counters[i] = 0; freq_counters[i] = 0; chmode_counters[i] = 0; } vsn_counters[3] = 0; freq_counters[3] = 0; chmode_counters[3] = 0; for (i = 4; i < 7; i++) { freq_counters[i] = 0; } /* skip ID3v2 header, if present */ mpeg_send_metadata(fdec, fd); /* use first valid mpeg frame header to retrieve stream info */ header = find_next_frame(fd, &bytecount, 0x100000, 0, is_ubr_allowed); /* Quit if we haven't found a valid header within 1M */ if (header == 0) return -1; memset(info, 0, sizeof(mp3info_t)); /* These two are needed for proper LAME gapless MP3 playback */ info->enc_delay = -1; info->enc_padding = -1; if (!mp3headerinfo(info, header)) return -2; offset = lseek(fd, 0, SEEK_CUR); lseek(fd, offset, SEEK_SET); memset(info, 0, sizeof(mp3info_t)); info->start_byteoffset = offset - 4; info->enc_delay = -1; info->enc_padding = -1; if (!mp3headerinfo(info, header)) return -2; #ifdef MPEG_DEBUG printf("start_byteoffset = %d\n", info->start_byteoffset); #endif if (info->frame_size == 0) { /* free-format MPEG - no VBR allowed. we have to find the next frame, so we can determine the frame size & bitrate */ long offset_next; long header_next; mp3info_t info_next; int cntdown = 8; do { header_next = find_next_frame(fd, &bytecount, 0x20000, 0, 1); /* Quit if we haven't found a valid header within 128K */ if (header_next == 0) return -1; memset(&info_next, 0, sizeof(mp3info_t)); /* These two are needed for proper LAME gapless MP3 playback */ info_next.enc_delay = -1; info_next.enc_padding = -1; if (!mp3headerinfo(&info_next, header_next)) return -2; --cntdown; } while (cntdown > 0 && !vlfc_cmp(info, &info_next)); if (cntdown == 0 && is_ubr_allowed) { fprintf(stderr, "dec_mpeg: corrupt stream, falling back to non-UBR only detection.\n"); is_ubr_allowed = 0; lseek(fd, 0, SEEK_SET); goto begin_info; } offset_next = lseek(fd, 0, SEEK_CUR); info->frame_size = offset_next - offset; lseek(fd, offset - 4, SEEK_SET); /* go back to beginning of stream */ return bytecount; } /* OK, we have the first real frame. Let's see if it has a Xing header */ if ((ret = read(fd, frame, info->frame_size-4)) < 0) { #ifdef MPEG_DEBUG printf("read(): %s\n", strerror(ret)); #endif /* MPEG_DEBUG */ return -3; } /* calculate position of VBR header */ if (info->version == MPEG_VERSION1) { if (info->channel_mode == 3) /* mono */ vbrheader = frame + 17; else vbrheader = frame + 32; } else { if (info->channel_mode == 3) /* mono */ vbrheader = frame + 9; else vbrheader = frame + 17; } if (!memcmp(vbrheader, "Xing", 4) || !memcmp(vbrheader, "Info", 4)) { int i = 8; /* Where to start parsing info */ #ifdef MPEG_DEBUG printf("Xing/Info header\n"); #endif /* MPEG_DEBUG */ /* Remember where in the file the Xing header is */ info->vbr_header_pos = lseek(fd, 0, SEEK_CUR) - info->frame_size; /* We want to skip the Xing frame when playing the stream */ bytecount += info->frame_size; /* workaround some files that have padding bit set, but frame size is 417 bytes */ if (info->padding) { lseek(fd, -1, SEEK_CUR); } /* Now get the next frame to find out the real info about the mp3 stream */ header = find_next_frame(fd, &tmp, 0x20000, 0, is_ubr_allowed); if(header == 0) return -4; if(!mp3headerinfo(info, header)) return -5; /* Is it a VBR file? */ info->is_vbr = info->is_xing_vbr = !memcmp(vbrheader, "Xing", 4); if (vbrheader[7] & VBR_FRAMES_FLAG) { /* Is the frame count there? */ info->frame_count = BYTES2INT(vbrheader[i], vbrheader[i+1], vbrheader[i+2], vbrheader[i+3]); if (info->frame_count <= ULONG_MAX / info->ft_num) info->file_time = info->frame_count * info->ft_num / info->ft_den; else info->file_time = info->frame_count / info->ft_den * info->ft_num; i += 4; } if (vbrheader[7] & VBR_BYTES_FLAG) { /* Is byte count there? */ info->byte_count = BYTES2INT(vbrheader[i], vbrheader[i+1], vbrheader[i+2], vbrheader[i+3]); i += 4; } if (info->file_time && info->byte_count) { if (info->byte_count <= (ULONG_MAX/8)) info->bitrate = info->byte_count * 8 / info->file_time; else info->bitrate = info->byte_count / (info->file_time >> 3); } else { info->bitrate = 0; } if (vbrheader[7] & VBR_TOC_FLAG) { /* Is table-of-contents there? */ memcpy(info->toc, vbrheader+i, 100); i += 100; } if (vbrheader[7] & VBR_QUALITY_FLAG) { /* We don't care about this, but need to skip it */ i += 4; } i += 21; info->enc_delay = (vbrheader[i] << 4) | (vbrheader[i + 1] >> 4); info->enc_padding = ((vbrheader[i + 1] & 0x0f) << 8) | vbrheader[i + 2]; if (!(info->enc_delay >= 0 && info->enc_delay <= 1152 && info->enc_padding >= 0 && info->enc_padding <= 2*1152)) { /* Invalid data */ info->enc_delay = -1; info->enc_padding = -1; } } if (!memcmp(vbrheader, "VBRI", 4)) { #ifdef MPEG_DEBUG printf("VBRI header\n"); #endif /* MPEG_DEBUG */ /* We want to skip the VBRI frame when playing the stream */ bytecount += info->frame_size; /* Now get the next frame to find out the real info about the mp3 stream */ header = find_next_frame(fd, &tmp, 0x20000, 0, is_ubr_allowed); if(header == 0) return -6; bytecount += tmp; if(!mp3headerinfo(info, header)) return -7; #ifdef MPEG_DEBUG printf("%04x: %04x %04x ", 0, header >> 16, header & 0xffff); for(i = 4;i < (int)sizeof(frame)-4;i+=2) { if(i % 16 == 0) { printf("\n%04x: ", i-4); } printf("%04x ", (frame[i-4] << 8) | frame[i-4+1]); } printf("\n"); #endif /* MPEG_DEBUG */ /* Yes, it is a FhG VBR file */ info->is_vbr = 1; info->is_vbri_vbr = 1; info->has_toc = 0; /* We don't parse the TOC (yet) */ info->byte_count = BYTES2INT(vbrheader[10], vbrheader[11], vbrheader[12], vbrheader[13]); info->frame_count = BYTES2INT(vbrheader[14], vbrheader[15], vbrheader[16], vbrheader[17]); if (info->frame_count <= ULONG_MAX / info->ft_num) info->file_time = info->frame_count * info->ft_num / info->ft_den; else info->file_time = info->frame_count / info->ft_den * info->ft_num; if (info->byte_count <= (ULONG_MAX/8)) info->bitrate = info->byte_count * 8 / info->file_time; else info->bitrate = info->byte_count / (info->file_time >> 3); /* We don't parse the TOC, since we don't yet know how to (FIXME) */ num_offsets = BYTES2INT(0, 0, vbrheader[18], vbrheader[19]); frames_per_entry = BYTES2INT(0, 0, vbrheader[24], vbrheader[25]); #ifdef MPEG_DEBUG printf("Frame size (%dkpbs): %d bytes (0x%x)\n", info->bitrate, info->frame_size, info->frame_size); printf("Frame count: %x\n", info->frame_count); printf("Byte count: %x\n", info->byte_count); printf("Offsets: %d\n", num_offsets); printf("Frames/entry: %d\n", frames_per_entry); #endif /* MPEG_DEBUG */ offset = 0; for(i = 0;i < num_offsets;i++) { j = BYTES2INT(0, 0, vbrheader[26+i*2], vbrheader[27+i*2]); offset += j; #ifdef MPEG_DEBUG printf("%03d: %x (%x)\n", i, offset - bytecount, j); #endif /* MPEG_DEBUG */ } } return bytecount; } void * build_seek_table_thread(void * args) { mpeg_pdata_t * pd = (mpeg_pdata_t *) args; int cnt = 0; int table_index = 0; long long sample_offset = 0; char * bytes = (char *)pd->fdm; long i; int div; long last = 0, last_but_1 = 0; long limit = pd->filesize-4; pd->builder_thread_running = 1; if (pd->mp3info.is_vbr) { div = pd->mp3info.frame_count / 100; } else { unsigned long frame_count = (pd->filesize - pd->mp3info.start_byteoffset) / pd->mp3info.frame_size; div = frame_count / 100; } if (div < 1) { #ifdef MPEG_DEBUG printf("track is too short, not building seek table\n"); #endif /* MPEG_DEBUG */ AQUALUNG_THREAD_DETACH() return NULL; } #ifdef MPEG_DEBUG printf("building seek table, div = %d\n", div); #endif /* MPEG_DEBUG */ /* look for id3v1 tag at the end of file */ if (pd->filesize >= 128 + 4) { if ((bytes[pd->filesize-128] == 'T') && (bytes[pd->filesize-127] == 'A') && (bytes[pd->filesize-126] == 'G')) { #ifdef MPEG_DEBUG printf("ID3v1 tag found at end of file\n"); #endif /* MPEG_DEBUG */ limit -= 128; } } for (i = pd->mp3info.start_byteoffset; i < limit;) { long header = BYTES2INT(bytes[i], bytes[i+1], bytes[i+2], bytes[i+3]); mp3info_t mp3info; if (is_mp3frameheader(header, 1)) { mp3headerinfo(&mp3info, header); if ((mp3info.layer == pd->mp3info.layer) && (mp3info.version == pd->mp3info.version) && (mp3info.channel_mode == pd->mp3info.channel_mode) && (mp3info.frequency == pd->mp3info.frequency)) { last_but_1 = last; last = i; if ((cnt % div == 0) && (table_index < 100)) { #ifdef MPEG_DEBUG printf("idx %2d | offset %8ld | sample %9lld\n", table_index, i, sample_offset); #endif /* MPEG_DEBUG */ pd->seek_table[table_index].frame = cnt; pd->seek_table[table_index].sample = sample_offset; pd->seek_table[table_index].offset = i; ++table_index; } sample_offset += mp3info.frame_samples; if (mp3info.frame_size == 0) { i += pd->mp3info.frame_size; } else { i += mp3info.frame_size; } ++cnt; } else { ++i; } } else { ++i; } if (!pd->builder_thread_running) { /* we were cancelled by the file decoder main thread */ #ifdef MPEG_DEBUG printf("seek table builder thread cancelled, exiting.\n"); #endif /* MPEG_DEBUG */ AQUALUNG_THREAD_DETACH() return NULL; } } if (table_index > 0 && table_index < 100) { int j; for (j = table_index; j < 100; j++) { pd->seek_table[j].frame = pd->seek_table[table_index-1].frame; pd->seek_table[j].sample = pd->seek_table[table_index-1].sample; pd->seek_table[j].offset = pd->seek_table[table_index-1].offset; } } #ifdef MPEG_DEBUG { i = last; long header = BYTES2INT(bytes[i], bytes[i+1], bytes[i+2], bytes[i+3]); mp3info_t mp3info; mp3headerinfo(&mp3info, header); printf("last frame position = %ld\n", limit + 4 - i); printf("last frame length = %d samp = %d\n", mp3info.frame_size, mp3info.frame_samples); } #endif /* MPEG_DEBUG */ pd->last_frames[1] = last_but_1; pd->last_frames[0] = last; #ifdef MPEG_DEBUG printf("seek table builder thread finished, cnt = %d\n", cnt); printf("last_frames[1] = %ld\n", pd->last_frames[1]); printf("last_frames[0] = %ld\n", pd->last_frames[0]); #endif /* MPEG_DEBUG */ pd->builder_thread_running = 0; AQUALUNG_THREAD_DETACH() return NULL; } void build_seek_table(mpeg_pdata_t * pd) { AQUALUNG_THREAD_CREATE(pd->seek_builder_id, NULL, build_seek_table_thread, pd) } void pause_mpeg_stream(decoder_t * dec) { mpeg_pdata_t * pd = (mpeg_pdata_t *)dec->pdata; char flush_dest; httpc_close(pd->session); if (pd->session->type == HTTPC_SESSION_STREAM) { /* empty mpeg decoder ringbuffer */ while (rb_read_space(pd->rb)) rb_read(pd->rb, &flush_dest, sizeof(char)); } } void resume_mpeg_stream(decoder_t * dec) { mpeg_pdata_t * pd = (mpeg_pdata_t *)dec->pdata; httpc_reconnect(pd->session); } /* MPEG input callback */ static enum mad_flow mpeg_input_stream(decoder_t * dec, struct mad_stream * stream) { mpeg_pdata_t * pd = (mpeg_pdata_t *)dec->pdata; size_t remaining; size_t read_length; unsigned char * read_start; unsigned char * guard_ptr; if (stream->next_frame != NULL) { remaining = stream->bufend - stream->next_frame; memmove(pd->inbuf, stream->next_frame, remaining); read_start = pd->inbuf + remaining; read_length = MPEG_INBUF_SIZE - remaining; } else { read_length = MPEG_INBUF_SIZE; read_start = pd->inbuf; remaining = 0; } read_length = httpc_read(pd->session, (char *)read_start, read_length); if (read_length < 0) return MAD_FLOW_STOP; if (read_length == 0) { guard_ptr = read_start + read_length; memset(guard_ptr, 0, MAD_BUFFER_GUARD); read_length += MAD_BUFFER_GUARD; } mad_stream_buffer(stream, pd->inbuf, read_length + remaining); stream->error=0; return MAD_FLOW_CONTINUE; } static enum mad_flow mpeg_input(void * data, struct mad_stream * stream) { decoder_t * dec = (decoder_t *)data; file_decoder_t * fdec = dec->fdec; mpeg_pdata_t * pd = (mpeg_pdata_t *)dec->pdata; size_t size = 0; if (fdec->is_stream) { return mpeg_input_stream(dec, stream); } if (fstat(pd->fd, &(pd->mpeg_stat)) == -1 || pd->mpeg_stat.st_size == 0) return MAD_FLOW_STOP; size = pd->mpeg_stat.st_size; pd->fdm = mmap(0, size, PROT_READ, MAP_SHARED, pd->fd, 0); if (pd->fdm == MAP_FAILED) return MAD_FLOW_STOP; mad_stream_buffer(stream, pd->fdm + pd->mp3info.start_byteoffset, size - pd->mp3info.start_byteoffset); return MAD_FLOW_CONTINUE; } /* MPEG output callback */ static enum mad_flow mpeg_output(void * data, struct mad_header const * header, struct mad_pcm * pcm) { decoder_t * dec = (decoder_t *)data; mpeg_pdata_t * pd = (mpeg_pdata_t *)dec->pdata; file_decoder_t * fdec = dec->fdec; long pos_bytes; int end_count = pcm->length; int i = 0, j; unsigned long scale = 322122547; /* (1 << 28) * 1.2 */ int buf[2]; float fbuf[2]; int pad = pd->mp3info.enc_padding; if (pd->delay_frames > pcm->length) { pd->delay_frames -= pcm->length; #ifdef MPEG_DEBUG printf("skipping whole frame as part of encoder delay\n"); #endif /* MPEG_DEBUG */ return MAD_FLOW_CONTINUE; } else if (pd->delay_frames > 0) { i = pd->delay_frames; pd->delay_frames = 0; #ifdef MPEG_DEBUG printf("skipping %d samples of encoder delay\n", i); #endif /* MPEG_DEBUG */ } else { i = 0; } pos_bytes = (pd->mpeg_stream.this_frame - pd->mpeg_stream.buffer) + pd->mp3info.start_byteoffset + 10; if ((pad > 0) && (pd->last_frames[0] != -1) && (pos_bytes >= pd->last_frames[0])) { #ifdef MPEG_DEBUG printf(" *** last frame len=%d ***\n", pcm->length); #endif /* MPEG_DEBUG */ if (pad > pcm->length) { #ifdef MPEG_DEBUG printf("skipping whole frame\n"); #endif /* MPEG_DEBUG */ return MAD_FLOW_CONTINUE; } else { end_count = pcm->length - pad; #ifdef MPEG_DEBUG printf("skipping %d samples\n", pad); #endif /* MPEG_DEBUG */ } } else if ((pad > 0) && (pd->last_frames[1] != -1) && (pos_bytes >= pd->last_frames[1])) { #ifdef MPEG_DEBUG printf(" *** last but one frame len=%d***\n", pcm->length); #endif /* MPEG_DEBUG */ if (pad > pcm->length) { pad -= pcm->length; end_count = pcm->length - pad; #ifdef MPEG_DEBUG printf("skipping %d samples\n", pad); #endif /* MPEG_DEBUG */ } } for (; i < end_count; i++) { for (j = 0; j < pd->channels; j++) { buf[j] = pd->error ? 0 : *(pcm->samples[j] + i); fbuf[j] = (double)buf[j] * fdec->voladj_lin / scale; } if (fdec->is_stream && pcm->channels == 1) { fbuf[1] = fbuf[0]; } if (rb_write_space(pd->rb) >= pd->channels * sample_size) { rb_write(pd->rb, (char *)fbuf, pd->channels * sample_size); } } pd->frame_counter++; pd->error = 0; return MAD_FLOW_CONTINUE; } /* MPEG header callback */ static enum mad_flow mpeg_header(void * data, struct mad_header const * header) { decoder_t * dec = (decoder_t *)data; mpeg_pdata_t * pd = (mpeg_pdata_t *)dec->pdata; file_decoder_t * fdec = dec->fdec; if (pd->bitrate != header->bitrate) { pd->bitrate = header->bitrate; } if (fdec->fileinfo.sample_rate != header->samplerate) { fdec->fileinfo.sample_rate = header->samplerate; } return MAD_FLOW_CONTINUE; } /* MPEG error callback */ static enum mad_flow mpeg_error(void * data, struct mad_stream * stream, struct mad_frame * frame) { decoder_t * dec = (decoder_t *)data; mpeg_pdata_t * pd = (mpeg_pdata_t *)dec->pdata; pd->error = 1; return MAD_FLOW_CONTINUE; } /* Main decode loop: return 1 if reached end of stream, 0 else */ int decode_mpeg(decoder_t * dec) { mpeg_pdata_t * pd = (mpeg_pdata_t *)dec->pdata; file_decoder_t * fdec = dec->fdec; if (mad_header_decode(&(pd->mpeg_frame.header), &(pd->mpeg_stream)) == -1) { if (pd->mpeg_stream.error == MAD_ERROR_BUFLEN) { if (fdec->is_stream) { if (mpeg_input_stream(dec, &(pd->mpeg_stream)) == MAD_FLOW_STOP) return 1; } else { return 1; } } if (pd->mpeg_stream.error != MAD_ERROR_NONE && !MAD_RECOVERABLE(pd->mpeg_stream.error)) { fprintf(stderr, "libMAD: unrecoverable error in MPEG Audio stream\n"); mpeg_error((void *)dec, &(pd->mpeg_stream), &(pd->mpeg_frame)); } else { pd->error = 0; } } mpeg_header((void *)dec, &(pd->mpeg_frame.header)); if (mad_frame_decode(&(pd->mpeg_frame), &(pd->mpeg_stream)) == -1) { if (pd->mpeg_stream.error == MAD_ERROR_BUFLEN) return 1; if (pd->mpeg_stream.error != MAD_ERROR_NONE && !MAD_RECOVERABLE(pd->mpeg_stream.error)) fprintf(stderr, "libMAD: unrecoverable error in MPEG Audio stream\n"); mpeg_error((void *)dec, &(pd->mpeg_stream), &(pd->mpeg_frame)); } mad_synth_frame(&(pd->mpeg_synth), &(pd->mpeg_frame)); mpeg_output((void *)dec, &(pd->mpeg_frame.header), &(pd->mpeg_synth.pcm)); return 0; } decoder_t * mpeg_decoder_init(file_decoder_t * fdec) { decoder_t * dec = NULL; if ((dec = calloc(1, sizeof(decoder_t))) == NULL) { fprintf(stderr, "dec_mpeg.c: mpeg_decoder_new() failed: calloc error\n"); return NULL; } dec->fdec = fdec; if ((dec->pdata = calloc(1, sizeof(mpeg_pdata_t))) == NULL) { fprintf(stderr, "dec_mpeg.c: mpeg_decoder_new() failed: calloc error\n"); return NULL; } dec->init = mpeg_decoder_init; dec->destroy = mpeg_decoder_destroy; dec->open = mpeg_decoder_open; dec->send_metadata = mpeg_decoder_send_metadata; dec->close = mpeg_decoder_close; dec->read = mpeg_decoder_read; dec->seek = mpeg_decoder_seek; return dec; } void mpeg_decoder_destroy(decoder_t * dec) { mpeg_pdata_t * pd = (mpeg_pdata_t *)dec->pdata; file_decoder_t * fdec = dec->fdec; if (fdec->is_stream) { httpc_del(pd->session); fdec->is_stream = 0; } free(dec->pdata); free(dec); } int mpeg_decoder_finish_open(decoder_t * dec) { mpeg_pdata_t * pd = (mpeg_pdata_t *)dec->pdata; file_decoder_t * fdec = dec->fdec; int i; /* data init (so when seeking we know if an entry is not yet filled in) */ for (i = 0; i < 100; i++) { pd->seek_table[i].frame = -1; } pd->builder_thread_running = 0; for (i = 0; i < 2; i++) { pd->last_frames[i] = -1; } pd->error = 0; pd->is_eos = 0; pd->seek_table_built = 0; pd->rb = rb_create(pd->channels * sample_size * RB_MAD_SIZE); fdec->fileinfo.channels = pd->channels; fdec->fileinfo.sample_rate = pd->SR; fdec->file_lib = MAD_LIB; strcpy(dec->format_str, "MPEG Audio"); if (pd->mpeg_subformat & 0xff7) { strcat(dec->format_str, " ("); switch (pd->mpeg_subformat & MPEG_LAYER_MASK) { case MPEG_LAYER_I: strcat(dec->format_str, _("Layer I")); break; case MPEG_LAYER_II: strcat(dec->format_str, _("Layer II")); break; case MPEG_LAYER_III: strcat(dec->format_str, _("Layer III")); break; default: strcat(dec->format_str, _("Unrecognized")); break; } } if ((pd->mpeg_subformat & MPEG_LAYER_MASK) && (pd->mpeg_subformat & (MPEG_MODE_MASK | MPEG_EMPH_MASK))) strcat(dec->format_str, ", "); switch (pd->mpeg_subformat & MPEG_MODE_MASK) { case MPEG_MODE_SINGLE: strcat(dec->format_str, _("Single channel")); break; case MPEG_MODE_DUAL: strcat(dec->format_str, _("Dual channel")); break; case MPEG_MODE_JOINT: strcat(dec->format_str, _("Joint stereo")); break; case MPEG_MODE_STEREO: strcat(dec->format_str, _("Stereo")); break; } if ((pd->mpeg_subformat & MPEG_MODE_MASK) && (pd->mpeg_subformat & MPEG_EMPH_MASK)) strcat(dec->format_str, ", "); switch (pd->mpeg_subformat & MPEG_EMPH_MASK) { case MPEG_EMPH_NONE: strcat(dec->format_str, _("Emphasis: none")); break; case MPEG_EMPH_5015: sprintf(dec->format_str, "%s%s 50/15 us", dec->format_str, _("Emphasis:")); break; case MPEG_EMPH_J_17: sprintf(dec->format_str, "%s%s CCITT J.17", dec->format_str, _("Emphasis:")); break; case MPEG_EMPH_RES: strcat(dec->format_str, _("Emphasis: reserved")); break; } strcat(dec->format_str, ")"); fdec->fileinfo.total_samples = pd->total_samples_est; fdec->fileinfo.bps = pd->bitrate; /* setup playback */ mad_stream_init(&(pd->mpeg_stream)); mad_frame_init(&(pd->mpeg_frame)); mad_synth_init(&(pd->mpeg_synth)); if (fdec->is_stream) { mad_stream_buffer(&pd->mpeg_stream, pd->inbuf, 0); } else { if (mpeg_input((void *)dec, &(pd->mpeg_stream)) == MAD_FLOW_STOP) { mad_synth_finish(&(pd->mpeg_synth)); mad_frame_finish(&(pd->mpeg_frame)); mad_stream_finish(&(pd->mpeg_stream)); return DECODER_OPEN_FERROR; } } pd->frame_counter = 0; #ifdef MPEG_DEBUG printf("mpeg_decoder_open successful\n"); #endif /* MPEG_DEBUG */ return DECODER_OPEN_SUCCESS; } int mpeg_decoder_open(decoder_t * dec, char * filename) { file_decoder_t * fdec = dec->fdec; mpeg_pdata_t * pd = (mpeg_pdata_t *)dec->pdata; struct stat exp_stat; if (!is_valid_extension(valid_extensions_mpeg, filename, 0)) { #ifdef MPEG_DEBUG printf("invalid extension of %s\n", filename); #endif /* MPEG_DEBUG */ return DECODER_OPEN_BADLIB; } fdec->is_stream = 0; if ((pd->fd = open(filename, O_RDONLY)) == 0) { fprintf(stderr, "mpeg_decoder_open: open() failed for MPEG Audio file\n"); return DECODER_OPEN_FERROR; } fstat(pd->fd, &exp_stat); pd->filesize = exp_stat.st_size; pd->SR = pd->channels = pd->bitrate = pd->mpeg_subformat = 0; pd->error = 0; pd->skip_bytes = get_mp3file_info(dec); close(pd->fd); #ifdef MPEG_DEBUG printf("skip_bytes = %ld\n\n", pd->skip_bytes); #endif /* MPEG_DEBUG */ if (pd->skip_bytes < 0) { return DECODER_OPEN_BADLIB; } #ifdef MPEG_DEBUG printf("version = %d\n", pd->mp3info.version); printf("layer = %d\n", pd->mp3info.layer); printf("bitrate = %d\n", pd->mp3info.bitrate); printf("frequency = %d\n", pd->mp3info.frequency); printf("channel_mode = %d\n", pd->mp3info.channel_mode); printf("mode_extension = %d\n", pd->mp3info.mode_extension); printf("emphasis = %d\n", pd->mp3info.emphasis); printf("frame_size = %d\n", pd->mp3info.frame_size); printf("frame_samples = %d\n", pd->mp3info.frame_samples); printf("is_vbr = %d\n", pd->mp3info.is_vbr); printf("has_toc = %d\n", pd->mp3info.has_toc); printf("frame_count = %ld\n", pd->mp3info.frame_count); printf("byte_count = %ld\n", pd->mp3info.byte_count); printf("file_time = %ld\n", pd->mp3info.file_time); printf("enc_delay = %ld\n", pd->mp3info.enc_delay); printf("enc_padding = %ld\n", pd->mp3info.enc_padding); #endif /* MPEG_DEBUG */ pd->SR = pd->mp3info.frequency; pd->bitrate = pd->mp3info.bitrate * 1000; switch (pd->mp3info.layer) { case 0: pd->mpeg_subformat |= MPEG_LAYER_I; break; case 1: pd->mpeg_subformat |= MPEG_LAYER_II; break; case 2: pd->mpeg_subformat |= MPEG_LAYER_III; break; } switch (pd->mp3info.channel_mode) { case 0: pd->mpeg_subformat |= MPEG_MODE_STEREO; pd->channels = 2; break; case 1: pd->mpeg_subformat |= MPEG_MODE_JOINT; pd->channels = 2; break; case 2: pd->mpeg_subformat |= MPEG_MODE_DUAL; pd->channels = 2; break; case 3: pd->mpeg_subformat |= MPEG_MODE_SINGLE; pd->channels = 1; break; } switch (pd->mp3info.emphasis) { case 0: pd->mpeg_subformat |= MPEG_EMPH_NONE; break; case 1: pd->mpeg_subformat |= MPEG_EMPH_5015; break; case 2: pd->mpeg_subformat |= MPEG_EMPH_RES; break; case 3: pd->mpeg_subformat |= MPEG_EMPH_J_17; break; } if ((!pd->SR) || (!pd->channels)) { return DECODER_OPEN_BADLIB; } if ((pd->channels != 1) && (pd->channels != 2)) { fprintf(stderr, "mpeg_decoder_open: MPEG Audio file with %d channels " "is unsupported\n", pd->channels); return DECODER_OPEN_FERROR; } if (pd->mp3info.is_vbr) { pd->total_samples_est = (double)pd->SR * pd->mp3info.file_time / 1000.0f; dec->format_flags |= FORMAT_VBR; } else { if (pd->bitrate == 0) { pd->total_samples_est = (long long)(pd->filesize - pd->mp3info.start_byteoffset) * pd->mp3info.frame_samples / pd->mp3info.frame_size; pd->bitrate = pd->mp3info.bitrate = 8 * (double)(pd->filesize - pd->mp3info.start_byteoffset) / (pd->total_samples_est / pd->SR); dec->format_flags |= FORMAT_UBR; } else { pd->total_samples_est = (double)(pd->filesize - pd->mp3info.start_byteoffset) / pd->bitrate * 8 * pd->SR; } } if (pd->mp3info.enc_delay > 0) { pd->delay_frames = pd->mp3info.enc_delay + 528 + pd->mp3info.frame_samples; } else { pd->delay_frames = 0; } pd->fd = open(filename, O_RDONLY); return mpeg_decoder_finish_open(dec); } void mpeg_decoder_send_metadata(decoder_t * dec) { file_decoder_t * fdec = dec->fdec; if (fdec->meta != NULL && fdec->meta_cb != NULL) { fdec->meta_cb(fdec->meta, fdec->meta_cbdata); } } int mpeg_stream_decoder_open(decoder_t * dec, http_session_t * session) { mpeg_pdata_t * pd = (mpeg_pdata_t *)dec->pdata; file_decoder_t * fdec = dec->fdec; pd->inbuf = calloc(MPEG_INBUF_SIZE+MAD_BUFFER_GUARD, 1); if (pd->inbuf == NULL) { fprintf(stderr, "mpeg_stream_decoder_open: calloc error\n"); return DECODER_OPEN_FERROR; } pd->channels = 2; pd->SR = 44100; pd->total_samples_est = 0; pd->bitrate = 1000 * session->headers.icy_br; /* XXX: this is just so we can display something */ pd->mpeg_subformat |= MPEG_LAYER_III; pd->mpeg_subformat |= MPEG_MODE_STEREO; pd->mpeg_subformat |= MPEG_EMPH_NONE; fdec->is_stream = 1; pd->session = session; dec->pause = pause_mpeg_stream; dec->resume = resume_mpeg_stream; return mpeg_decoder_finish_open(dec); } void mpeg_decoder_close(decoder_t * dec) { mpeg_pdata_t * pd = (mpeg_pdata_t *)dec->pdata; file_decoder_t * fdec = dec->fdec; /* take care of seek table builder thread, if there is any */ if (pd->builder_thread_running) { pd->builder_thread_running = 0; #ifdef MPEG_DEBUG printf("joining seek table builder thread\n"); #endif /* MPEG_DEBUG */ AQUALUNG_THREAD_JOIN(pd->seek_builder_id) #ifdef MPEG_DEBUG printf("joined seek table builder thread\n"); #endif /* MPEG_DEBUG */ } mad_synth_finish(&(pd->mpeg_synth)); mad_frame_finish(&(pd->mpeg_frame)); mad_stream_finish(&(pd->mpeg_stream)); if (fdec->is_stream) { free(pd->inbuf); httpc_close(pd->session); } else { if (munmap(pd->fdm, pd->mpeg_stat.st_size) == -1) fprintf(stderr, "Error while munmap()'ing MPEG Audio file mapping\n"); close(pd->fd); } rb_free(pd->rb); #ifdef MPEG_DEBUG printf("mpeg_decoder_close successful\n"); #endif /* MPEG_DEBUG */ } unsigned int mpeg_decoder_read(decoder_t * dec, float * dest, int num) { mpeg_pdata_t * pd = (mpeg_pdata_t *)dec->pdata; file_decoder_t * fdec = dec->fdec; unsigned int numread = 0; unsigned int n_avail = 0; if (!fdec->is_stream && !pd->seek_table_built) { #ifdef MPEG_DEBUG printf("first read from mpeg file\n"); #endif /* MPEG_DEBUG */ /* read mmap'ed file and build seek table in background thread. we do this upon the first read, so it doesn't start when we open a mass of files, but don't read any audio (metadata retrieval, etc) */ build_seek_table(pd); pd->seek_table_built = 1; } while ((rb_read_space(pd->rb) < num * pd->channels * sample_size) && (!pd->is_eos)) { pd->is_eos = decode_mpeg(dec); } n_avail = rb_read_space(pd->rb) / (pd->channels * sample_size); if (n_avail > num) n_avail = num; rb_read(pd->rb, (char *)dest, n_avail * pd->channels * sample_size); numread = n_avail; return numread; } void mpeg_decoder_seek(decoder_t * dec, unsigned long long seek_to_pos) { mpeg_pdata_t * pd = (mpeg_pdata_t *)dec->pdata; file_decoder_t * fdec = dec->fdec; char * bytes = (char *)pd->fdm; long header; mp3info_t mp3info; char flush_dest; int i; unsigned long offset; unsigned long long sample; #ifdef MPEG_DEBUG int cnt = 0; #endif /* MPEG_DEBUG */ if (seek_to_pos < pd->mp3info.frame_samples) { pd->frame_counter = 0; pd->mpeg_stream.next_frame = pd->mpeg_stream.buffer; fdec->samples_left = fdec->fileinfo.total_samples; goto flush_decoder_rb; } /* search for closest preceding entry in seek table */ for (i = 0; i < 99; i++) { if (pd->seek_table[i].frame == -1) { /* uninitialized seek table (to the desired position, at least) so we fall back on conventional bitstream seeking */ #ifdef MPEG_DEBUG printf("seek table not yet ready, seeking bitstream.\n"); #endif /* MPEG_DEBUG */ pd->mpeg_stream.next_frame = pd->mpeg_stream.buffer; mad_stream_sync(&(pd->mpeg_stream)); mad_stream_skip(&(pd->mpeg_stream), (pd->filesize - pd->mp3info.start_byteoffset) * (double)seek_to_pos / pd->total_samples_est); mad_stream_sync(&(pd->mpeg_stream)); pd->is_eos = decode_mpeg(dec); /* report the real position of the decoder */ fdec->samples_left = fdec->fileinfo.total_samples - (pd->mpeg_stream.next_frame - pd->mpeg_stream.buffer) / pd->bitrate * 8 * pd->SR; goto flush_decoder_rb; } if (pd->seek_table[i+1].sample > seek_to_pos) break; } offset = pd->seek_table[i].offset; sample = pd->seek_table[i].sample; #ifdef MPEG_DEBUG printf("seek table: byte_offset = %d sample_pos = %d\n", offset, sample); #endif /* MPEG_DEBUG */ do { if (offset > pd->filesize - 4) { offset = pd->filesize-4; break; } header = BYTES2INT(bytes[offset], bytes[offset+1], bytes[offset+2], bytes[offset+3]); if (is_mp3frameheader(header, 1)) { mp3headerinfo(&mp3info, header); if ((mp3info.layer == pd->mp3info.layer) && (mp3info.version == pd->mp3info.version) && (mp3info.frequency == pd->mp3info.frequency)) { sample += mp3info.frame_samples; offset += mp3info.frame_size; #ifdef MPEG_DEBUG cnt += mp3info.frame_size; #endif /* MPEG_DEBUG */ } else { ++offset; #ifdef MPEG_DEBUG ++cnt; #endif /* MPEG_DEBUG */ } } else { ++offset; #ifdef MPEG_DEBUG ++cnt; #endif /* MPEG_DEBUG */ } } while (sample + mp3info.frame_samples < seek_to_pos); #ifdef MPEG_DEBUG printf("stream nudged by %d bytes\n", cnt); #endif /* MPEG_DEBUG */ pd->mpeg_stream.next_frame = pd->mpeg_stream.buffer - pd->mp3info.start_byteoffset + offset; fdec->samples_left = fdec->fileinfo.total_samples - sample; flush_decoder_rb: /* empty mpeg decoder ringbuffer */ while (rb_read_space(pd->rb)) rb_read(pd->rb, &flush_dest, sizeof(char)); } #else decoder_t * mpeg_decoder_init(file_decoder_t * fdec) { return NULL; } #endif /* HAVE_MPEG */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/decoder/dec_null.h0000644000175000001440000000275211243310677015256 00000000000000/* -*- linux-c -*- Copyright (C) 2005 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: dec_null.h 1068 2009-07-24 12:02:30Z peterszilagyi $ */ #ifndef _DEC_NULL_H #define _DEC_NULL_H #include "file_decoder.h" /* private data of the decoder */ typedef struct _null_pdata_t { int dummy; } null_pdata_t; decoder_t * null_decoder_init(file_decoder_t * fdec); void null_decoder_destroy(decoder_t * dec); int null_decoder_open(decoder_t * dec, char * filename); void null_decoder_send_metadata(decoder_t * dec); void null_decoder_close(decoder_t * dec); unsigned int null_decoder_read(decoder_t * dec, float * dest, int num); void null_decoder_seek(decoder_t * dec, unsigned long long seek_to_pos); #endif /* _DEC_NULL_H */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/decoder/dec_null.c0000644000175000001440000000643711243310677015255 00000000000000/* -*- linux-c -*- Copyright (C) 2005 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: dec_null.c 1068 2009-07-24 12:02:30Z peterszilagyi $ */ #include #include #include #include "dec_null.h" decoder_t * null_decoder_init(file_decoder_t * fdec) { decoder_t * dec = NULL; if ((dec = calloc(1, sizeof(decoder_t))) == NULL) { fprintf(stderr, "dec_null.c: null_decoder_new() failed: calloc error\n"); return NULL; } dec->fdec = fdec; if ((dec->pdata = calloc(1, sizeof(null_pdata_t))) == NULL) { fprintf(stderr, "dec_null.c: null_decoder_new() failed: calloc error\n"); return NULL; } dec->init = null_decoder_init; dec->destroy = null_decoder_destroy; dec->open = null_decoder_open; dec->send_metadata = null_decoder_send_metadata; dec->close = null_decoder_close; dec->read = null_decoder_read; dec->seek = null_decoder_seek; return dec; } void null_decoder_destroy(decoder_t * dec) { free(dec->pdata); free(dec); } int null_decoder_open(decoder_t * dec, char * filename) { /* declarations for easy data access: null_pdata_t * pd = (null_pdata_t *)dec->pdata; file_decoder_t * fdec = dec->fdec; */ /* do whatever is needed to open the file and determine whether this decoder is able to handle it. return one of the following: DECODER_OPEN_SUCCESS : this decoder is able to deal with the file and opening was successful. DECODER_OPEN_BADLIB : this decoder is not appropriate for this file. DECODER_OPEN_FERROR : file nonexistent/nonaccessible, so trying other decoders is pointless. If opening was successful, put a string describing the format/decoder in format_str[]: strcpy(dec->format_str, "NULL Audio"); */ return DECODER_OPEN_BADLIB; } void null_decoder_send_metadata(decoder_t * dec) { } void null_decoder_close(decoder_t * dec) { /* null_pdata_t * pd = (null_pdata_t *)dec->pdata; */ /* close the file */ } unsigned int null_decoder_read(decoder_t * dec, float * dest, int num) { /* null_pdata_t * pd = (null_pdata_t *)dec->pdata; file_decoder_t * fdec = dec->fdec; */ /* read num frames (mono or stereo) from the file. return the number of frames actually read. */ return 0; } void null_decoder_seek(decoder_t * dec, unsigned long long seek_to_pos) { /* null_pdata_t * pd = (null_pdata_t *)dec->pdata; file_decoder_t * fdec = dec->fdec; */ /* seek to seek_to_pos sample position in the file. */ } // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/decoder/dec_sndfile.h0000644000175000001440000000327311243310677015727 00000000000000/* -*- linux-c -*- Copyright (C) 2005 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: dec_sndfile.h 1068 2009-07-24 12:02:30Z peterszilagyi $ */ #ifndef _DEC_SNDFILE_H #define _DEC_SNDFILE_H #ifdef HAVE_SNDFILE #include #endif /* HAVE_SNDFILE */ #include "file_decoder.h" #ifdef HAVE_SNDFILE typedef struct _sndfile_pdata_t { SF_INFO sf_info; SNDFILE * sf; unsigned int nframes; } sndfile_pdata_t; #endif /* HAVE_SNDFILE */ decoder_t * sndfile_decoder_init(file_decoder_t * fdec); #ifdef HAVE_SNDFILE void sndfile_decoder_destroy(decoder_t * dec); int sndfile_decoder_open(decoder_t * dec, char * filename); void sndfile_decoder_send_metadata(decoder_t * dec); void sndfile_decoder_close(decoder_t * dec); unsigned int sndfile_decoder_read(decoder_t * dec, float * dest, int num); void sndfile_decoder_seek(decoder_t * dec, unsigned long long seek_to_pos); #endif /* HAVE_SNDFILE */ #endif /* _DEC_SNDFILE_H */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/decoder/dec_sndfile.c0000644000175000001440000002223111243310677015715 00000000000000/* -*- linux-c -*- Copyright (C) 2005 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: dec_sndfile.c 1068 2009-07-24 12:02:30Z peterszilagyi $ */ #include #include #include #include #include "../i18n.h" #include "dec_sndfile.h" #ifdef HAVE_SNDFILE /* list of accepted file extensions */ char * valid_extensions_sndfile[] = { "wav", "aiff", "au", "w64", "voc", "xi", "htk", "svx", NULL }; decoder_t * sndfile_decoder_init(file_decoder_t * fdec) { decoder_t * dec = NULL; if ((dec = calloc(1, sizeof(decoder_t))) == NULL) { fprintf(stderr, "dec_sndfile.c: sndfile_decoder_new() failed: calloc error\n"); return NULL; } dec->fdec = fdec; if ((dec->pdata = calloc(1, sizeof(sndfile_pdata_t))) == NULL) { fprintf(stderr, "dec_sndfile.c: sndfile_decoder_new() failed: calloc error\n"); return NULL; } dec->init = sndfile_decoder_init; dec->destroy = sndfile_decoder_destroy; dec->open = sndfile_decoder_open; dec->send_metadata = sndfile_decoder_send_metadata; dec->close = sndfile_decoder_close; dec->read = sndfile_decoder_read; dec->seek = sndfile_decoder_seek; return dec; } void sndfile_decoder_destroy(decoder_t * dec) { free(dec->pdata); free(dec); } int sndfile_decoder_open(decoder_t * dec, char * filename) { sndfile_pdata_t * pd = (sndfile_pdata_t *)dec->pdata; file_decoder_t * fdec = dec->fdec; pd->sf_info.format = 0; if ((pd->sf = sf_open(filename, SFM_READ, &(pd->sf_info))) == NULL) { return DECODER_OPEN_BADLIB; } #ifdef HAVE_SNDFILE_1_0_12 /* XXX don't use the FLAC decoder in sndfile, seeking seems to be buggy */ /* the native FLAC decoder will catch the file instead. */ if ((pd->sf_info.format & SF_FORMAT_TYPEMASK) == SF_FORMAT_FLAC) { sf_close(pd->sf); return DECODER_OPEN_BADLIB; } #endif /* HAVE_SNDFILE_1_0_12 */ #ifdef HAVE_SNDFILE_1_0_18 /* XXX don't use the Ogg decoder in sndfile. */ if ((pd->sf_info.format & SF_FORMAT_SUBMASK) == SF_FORMAT_VORBIS) { sf_close(pd->sf); return DECODER_OPEN_BADLIB; } #endif /* HAVE_SNDFILE_1_0_18 */ if ((pd->sf_info.channels != 1) && (pd->sf_info.channels != 2)) { fprintf(stderr, "sndfile_decoder_open: sndfile with %d channels is unsupported\n", pd->sf_info.channels); return DECODER_OPEN_FERROR; } fdec->fileinfo.channels = pd->sf_info.channels; fdec->fileinfo.sample_rate = pd->sf_info.samplerate; fdec->fileinfo.total_samples = pd->sf_info.frames; fdec->file_lib = SNDFILE_LIB; switch (pd->sf_info.format & SF_FORMAT_SUBMASK) { case SF_FORMAT_PCM_S8: case SF_FORMAT_PCM_U8: fdec->fileinfo.bps = 8; break; case SF_FORMAT_PCM_16: fdec->fileinfo.bps = 16; break; case SF_FORMAT_PCM_24: fdec->fileinfo.bps = 24; break; case SF_FORMAT_PCM_32: case SF_FORMAT_FLOAT: fdec->fileinfo.bps = 32; break; case SF_FORMAT_DOUBLE: fdec->fileinfo.bps = 64; break; default: /* XXX libsndfile knows some more formats apart from the ones above, but i don't know their bits/sample... perhaps i'm stupid. --tszilagyi */ fdec->fileinfo.bps = 0; break; } fdec->fileinfo.bps *= fdec->fileinfo.sample_rate * fdec->fileinfo.channels; switch (pd->sf_info.format & SF_FORMAT_TYPEMASK) { case SF_FORMAT_WAV: strcpy(dec->format_str, "Microsoft WAV"); break; case SF_FORMAT_AIFF: strcpy(dec->format_str, "Apple/SGI AIFF"); break; case SF_FORMAT_AU: strcpy(dec->format_str, "Sun/NeXT AU"); break; case SF_FORMAT_PAF: strcpy(dec->format_str, "Ensoniq PARIS"); break; case SF_FORMAT_SVX: strcpy(dec->format_str, "Amiga IFF / SVX8 / SV16"); break; case SF_FORMAT_NIST: strcpy(dec->format_str, "Sphere NIST"); break; case SF_FORMAT_VOC: strcpy(dec->format_str, "VOC"); break; case SF_FORMAT_IRCAM: strcpy(dec->format_str, "Berkeley/IRCAM/CARL"); break; case SF_FORMAT_W64: strcpy(dec->format_str, "Sonic Foundry 64 bit RIFF/WAV"); break; case SF_FORMAT_MAT4: strcpy(dec->format_str, "Matlab (tm) V4.2 / GNU Octave 2.0"); break; #ifdef HAVE_SNDFILE_1_0_12 /* version(libsndfile) >= 1.0.12 */ case SF_FORMAT_PVF: strcpy(dec->format_str, "Portable Voice Format"); break; case SF_FORMAT_XI: strcpy(dec->format_str, "Fasttracker 2 Extended Instrument"); break; case SF_FORMAT_HTK: strcpy(dec->format_str, "HMM Tool Kit"); break; case SF_FORMAT_SDS: strcpy(dec->format_str, "Midi Sample Dump Standard"); break; case SF_FORMAT_AVR: strcpy(dec->format_str, "Audio Visual Research"); break; case SF_FORMAT_WAVEX: strcpy(dec->format_str, "MS WAVE with WAVEFORMATEX"); break; case SF_FORMAT_SD2: strcpy(dec->format_str, "Sound Designer 2"); break; case SF_FORMAT_FLAC: strcpy(dec->format_str, "FLAC"); break; case SF_FORMAT_CAF: strcpy(dec->format_str, "Core Audio File"); break; #endif /* HAVE_SNDFILE_1_0_12 */ } switch (pd->sf_info.format & SF_FORMAT_SUBMASK) { case SF_FORMAT_PCM_S8: sprintf(dec->format_str, "%s %s%s%s", dec->format_str, "(8 ", _("bit signed"), ")"); break; case SF_FORMAT_PCM_U8: sprintf(dec->format_str, "%s %s%s%s", dec->format_str, "(16 ", _("bit unsigned"), ")"); break; case SF_FORMAT_PCM_16: sprintf(dec->format_str, "%s %s%s%s", dec->format_str, "(16 ", _("bit signed"), ")"); break; case SF_FORMAT_PCM_24: sprintf(dec->format_str, "%s %s%s%s", dec->format_str, "(24 ", _("bit signed"), ")"); break; case SF_FORMAT_PCM_32: sprintf(dec->format_str, "%s %s%s%s", dec->format_str, "(32 ", _("bit signed"), ")"); break; case SF_FORMAT_FLOAT: sprintf(dec->format_str, "%s %s%s%s", dec->format_str, "(32 ", _("bit float"), ")"); break; case SF_FORMAT_DOUBLE: sprintf(dec->format_str, "%s %s%s%s", dec->format_str, "(64 ", _("bit double"), ")"); break; case SF_FORMAT_ULAW: sprintf(dec->format_str, "%s %s%s%s", dec->format_str, "(u-Law ", _("encoding"), ")"); break; case SF_FORMAT_ALAW: sprintf(dec->format_str, "%s %s%s%s", dec->format_str, "(A-Law ", _("encoding"), ")"); break; case SF_FORMAT_IMA_ADPCM: sprintf(dec->format_str, "%s %s%s%s", dec->format_str, "(IMA ADPCM ", _("encoding"), ")"); break; case SF_FORMAT_MS_ADPCM: sprintf(dec->format_str, "%s %s%s%s", dec->format_str, "(Microsoft ADPCM ", _("encoding"), ")"); break; case SF_FORMAT_GSM610: sprintf(dec->format_str, "%s %s%s%s", dec->format_str, "(GSM 6.10 ", _("encoding"), ")"); break; case SF_FORMAT_VOX_ADPCM: sprintf(dec->format_str, "%s %s%s%s", dec->format_str, "(Oki Dialogic ADPCM ", _("encoding"), ")"); break; case SF_FORMAT_G721_32: sprintf(dec->format_str, "%s %s%s%s", dec->format_str, "(32kbps G721 ADPCM ", _("encoding"), ")"); break; case SF_FORMAT_G723_24: sprintf(dec->format_str, "%s %s%s%s", dec->format_str, "(24kbps G723 ADPCM ", _("encoding"), ")"); break; case SF_FORMAT_G723_40: sprintf(dec->format_str, "%s %s%s%s", dec->format_str, "(40kbps G723 ADPCM ", _("encoding"), ")"); break; case SF_FORMAT_DWVW_12: sprintf(dec->format_str, "%s %s%s%s", dec->format_str, "(12 bit DWVW ", _("encoding"), ")"); break; case SF_FORMAT_DWVW_16: sprintf(dec->format_str, "%s %s%s%s", dec->format_str, "(16 bit DWVW ", _("encoding"), ")"); break; case SF_FORMAT_DWVW_24: sprintf(dec->format_str, "%s %s%s%s", dec->format_str, "(24 bit DWVW ", _("encoding"), ")"); break; case SF_FORMAT_DWVW_N: sprintf(dec->format_str, "%s %s%s%s", dec->format_str, "(N bit DWVW ", _("encoding"), ")"); break; } return DECODER_OPEN_SUCCESS; } void sndfile_decoder_send_metadata(decoder_t * dec) { } void sndfile_decoder_close(decoder_t * dec) { sndfile_pdata_t * pd = (sndfile_pdata_t *)dec->pdata; sf_close(pd->sf); } unsigned int sndfile_decoder_read(decoder_t * dec, float * dest, int num) { sndfile_pdata_t * pd = (sndfile_pdata_t *)dec->pdata; file_decoder_t * fdec = dec->fdec; int i; unsigned int numread = 0; numread = sf_readf_float(pd->sf, dest, num); for (i = 0; i < pd->sf_info.channels * numread; i++) { dest[i] *= fdec->voladj_lin; } return numread; } void sndfile_decoder_seek(decoder_t * dec, unsigned long long seek_to_pos) { sndfile_pdata_t * pd = (sndfile_pdata_t *)dec->pdata; file_decoder_t * fdec = dec->fdec; if ((pd->nframes = sf_seek(pd->sf, seek_to_pos, SEEK_SET)) != -1) { fdec->samples_left = fdec->fileinfo.total_samples - pd->nframes; } else { fprintf(stderr, "sndfile_decoder_seek: warning: sf_seek() failed\n"); } } #else decoder_t * sndfile_decoder_init(file_decoder_t * fdec) { return NULL; } #endif /* HAVE_SNDFILE */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/decoder/dec_speex.h0000644000175000001440000000405511243310677015426 00000000000000/* -*- linux-c -*- Copyright (C) 2005 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: dec_speex.h 1068 2009-07-24 12:02:30Z peterszilagyi $ */ #ifndef _DEC_SPEEX_H #define _DEC_SPEEX_H #ifdef HAVE_SPEEX #include #include #include #endif /* HAVE_SPEEX */ #include "file_decoder.h" /* Decoding buffer size for Speex */ #define SPEEX_BUFSIZE 1280 /* size of ringbuffer for decoded Speex data (in frames) */ #define RB_SPEEX_SIZE 262144 #ifdef HAVE_SPEEX typedef struct _speex_pdata_t { rb_t * rb; FILE * speex_file; OGGZ * oggz; SpeexBits bits; const SpeexMode * mode; void * decoder; int sample_rate; int channels; int vbr; int nframes; int frame_size; int exploring; int error; long packetno; int granulepos; int is_eos; } speex_pdata_t; #endif /* HAVE_SPEEX */ decoder_t * speex_dec_init(file_decoder_t * fdec); #ifdef HAVE_SPEEX void speex_dec_destroy(decoder_t * dec); int speex_dec_open(decoder_t * dec, char * filename); void speex_dec_send_metadata(decoder_t * dec); void speex_dec_close(decoder_t * dec); unsigned int speex_dec_read(decoder_t * dec, float * dest, int num); void speex_dec_seek(decoder_t * dec, unsigned long long seek_to_pos); #endif /* HAVE_SPEEX */ #endif /* _DEC_SPEEX_H */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/decoder/dec_speex.c0000644000175000001440000002224011243310677015415 00000000000000/* -*- linux-c -*- Copyright (C) 2005 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: dec_speex.c 1068 2009-07-24 12:02:30Z peterszilagyi $ */ #include #include #include #include #include "dec_speex.h" extern size_t sample_size; #ifdef HAVE_SPEEX static int read_ogg_packet(OGGZ * oggz, ogg_packet * op, long serialno, void * user_data) { decoder_t * dec = (decoder_t *)user_data; speex_pdata_t * pd = (speex_pdata_t *)dec->pdata; if (pd->exploring && (pd->packetno == 0)) { /* Speex header */ int i; int ptr = 0; char speex_string[9]; char speex_version[21]; int enh = 1; SpeexHeader * header; for (i = 0; i < 8; i++) { speex_string[i] = op->packet[ptr++]; } speex_string[i] = '\0'; for (i = 0; i < 20; i++) { speex_version[i] = op->packet[ptr++]; } speex_version[i] = '\0'; if (strcmp(speex_string, "Speex ") != 0) { printf("read_ogg_packet(): Not a Speex stream\n"); pd->error = 1; return 0; } speex_bits_init(&(pd->bits)); header = speex_packet_to_header((char *)op->packet, op->bytes); if (!header) { printf("Cannot read Speex header\n"); pd->error = 1; return 0; } pd->mode = speex_mode_list[header->mode]; if (pd->mode->bitstream_version > header->mode_bitstream_version) { fprintf(stderr, "Unknown bitstream version! The file was encoded with an older version of Speex.\n" "You need to downgrade Speex in order to play it.\n"); pd->error = 1; return 0; } if (pd->mode->bitstream_version < header->mode_bitstream_version) { fprintf(stderr, "Unknown bitstream version! The file was encoded with a newer version of Speex.\n" "You need to upgrade Speex in order to play it.\n"); pd->error = 1; return 0; } pd->sample_rate = header->rate; pd->channels = header->nb_channels; pd->vbr = header->vbr; if (header->frames_per_packet != 0) pd->nframes = header->frames_per_packet; pd->decoder = speex_decoder_init(pd->mode); speex_decoder_ctl(pd->decoder, SPEEX_GET_FRAME_SIZE, &(pd->frame_size)); speex_decoder_ctl(pd->decoder, SPEEX_SET_ENH, &enh); } else if (pd->packetno >= 2) { int j; float output_frame[SPEEX_BUFSIZE]; pd->granulepos = op->granulepos; if (!pd->exploring) { speex_bits_read_from(&(pd->bits), (char *)op->packet, op->bytes); for (j = 0; j < pd->nframes; j++) { int k; speex_decode(pd->decoder, &(pd->bits), output_frame); for (k = 0; k < pd->frame_size * pd->channels; k++) { output_frame[k] /= 32768.0f; if (output_frame[k] > 1.0f) { output_frame[k] = 1.0f; } else if (output_frame[k] < -1.0f) { output_frame[k] = -1.0f; } } rb_write(pd->rb, (char *)output_frame, pd->channels * pd->frame_size * sample_size); } } } ++pd->packetno; return 0; } /* return 1 if reached end of stream, 0 else */ int decode_speex(decoder_t * dec) { speex_pdata_t * pd = (speex_pdata_t *)dec->pdata; if (oggz_read(pd->oggz, 1024) > 0) { return 0; } else { return 1; } } decoder_t * speex_dec_init(file_decoder_t * fdec) { decoder_t * dec = NULL; if ((dec = calloc(1, sizeof(decoder_t))) == NULL) { fprintf(stderr, "dec_speex.c: speex_decoder_new() failed: calloc error\n"); return NULL; } dec->fdec = fdec; if ((dec->pdata = calloc(1, sizeof(speex_pdata_t))) == NULL) { fprintf(stderr, "dec_speex.c: speex_decoder_new() failed: calloc error\n"); return NULL; } dec->init = speex_dec_init; dec->destroy = speex_dec_destroy; dec->open = speex_dec_open; dec->send_metadata = speex_dec_send_metadata; dec->close = speex_dec_close; dec->read = speex_dec_read; dec->seek = speex_dec_seek; return dec; } void speex_dec_destroy(decoder_t * dec) { free(dec->pdata); free(dec); } int speex_dec_open(decoder_t * dec, char * filename) { speex_pdata_t * pd = (speex_pdata_t *)dec->pdata; file_decoder_t * fdec = dec->fdec; int enh = 1; char ogg_sig[4]; long length_in_bytes = 0; long length_in_samples = 0; if ((pd->speex_file = fopen(filename, "rb")) == NULL) { fprintf(stderr, "speex_decoder_open: fopen() failed\n"); return DECODER_OPEN_FERROR; } if (fread(ogg_sig, 1, 4, pd->speex_file) != 4) { fprintf(stderr, "couldn't read OGG signature from %s\n", filename); return DECODER_OPEN_FERROR; } if ((ogg_sig[0] != 'O') || (ogg_sig[1] != 'g') || (ogg_sig[2] != 'g') || (ogg_sig[3] != 'S')) { /* not an OGG stream */ fclose(pd->speex_file); return DECODER_OPEN_BADLIB; } if ((pd->oggz = oggz_open(filename, OGGZ_READ | OGGZ_AUTO)) == NULL) { printf("nonexistent or unaccessible file %s\n", filename); return DECODER_OPEN_FERROR; } oggz_set_read_callback(pd->oggz, -1, read_ogg_packet, dec); pd->packetno = 0; pd->exploring = 1; pd->error = 0; while (pd->packetno < 2) { /* process Speex header and comments */ oggz_read(pd->oggz, 1024); } if (pd->error != 0) { printf("Error opening Speex\n"); oggz_close(pd->oggz); return DECODER_OPEN_BADLIB; } /* parse ogg packets till eof to get the last granulepos */ while (oggz_read(pd->oggz, 1024) > 0) ; length_in_bytes = oggz_tell(pd->oggz); oggz_close(pd->oggz); speex_bits_destroy(&(pd->bits)); speex_decoder_destroy(pd->decoder); if ((pd->channels != 1) && (pd->channels != 2)) { printf("Sorry, Ogg Speex with %d channels is unsupported\n", pd->channels); return DECODER_OPEN_FERROR; } pd->packetno = 0; pd->exploring = 0; pd->error = 0; pd->oggz = oggz_open(filename, OGGZ_READ | OGGZ_AUTO); oggz_set_read_callback(pd->oggz, -1, read_ogg_packet, dec); speex_bits_init(&(pd->bits)); pd->decoder = speex_decoder_init(pd->mode); speex_decoder_ctl(pd->decoder, SPEEX_SET_ENH, &enh); pd->is_eos = 0; pd->rb = rb_create(pd->channels * sample_size * RB_SPEEX_SIZE); fdec->fileinfo.channels = pd->channels; fdec->fileinfo.sample_rate = pd->sample_rate; length_in_samples = pd->granulepos + pd->nframes - 1; fdec->fileinfo.total_samples = length_in_samples; fdec->fileinfo.bps = 8 * length_in_bytes / (length_in_samples / pd->sample_rate); fdec->file_lib = SPEEX_LIB; strcpy(dec->format_str, "Ogg Speex"); return DECODER_OPEN_SUCCESS; } void speex_dec_send_metadata(decoder_t * dec) { } void speex_dec_close(decoder_t * dec) { speex_pdata_t * pd = (speex_pdata_t *)dec->pdata; oggz_close(pd->oggz); speex_bits_destroy(&(pd->bits)); speex_decoder_destroy(pd->decoder); rb_free(pd->rb); } unsigned int speex_dec_read(decoder_t * dec, float * dest, int num) { speex_pdata_t * pd = (speex_pdata_t *)dec->pdata; unsigned int numread = 0; unsigned int n_avail = 0; while ((rb_read_space(pd->rb) < num * pd->channels * sample_size) && (!pd->is_eos)) { pd->is_eos = decode_speex(dec); } n_avail = rb_read_space(pd->rb) / (pd->channels * sample_size); if (n_avail > num) n_avail = num; rb_read(pd->rb, (char *)dest, n_avail * pd->channels * sample_size); numread = n_avail; return numread; } void speex_dec_seek(decoder_t * dec, unsigned long long seek_to_pos) { speex_pdata_t * pd = (speex_pdata_t *)dec->pdata; file_decoder_t * fdec = dec->fdec; char flush_dest; if (seek_to_pos == fdec->fileinfo.total_samples) --seek_to_pos; if (oggz_seek_units(pd->oggz, seek_to_pos / (float)pd->sample_rate * 1000.0f, SEEK_SET) != -1) { if (seek_to_pos == 0) { pd->packetno = 0; } fdec->samples_left = fdec->fileinfo.total_samples - seek_to_pos; /* empty speex decoder ringbuffer */ while (rb_read_space(pd->rb)) rb_read(pd->rb, &flush_dest, sizeof(char)); } else { fprintf(stderr, "speex_dec_seek(): warning: oggz_seek_units() returned -1\n"); } } #else decoder_t * speex_dec_init(file_decoder_t * fdec) { return NULL; } #endif /* HAVE_SPEEX */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/decoder/dec_vorbis.h0000644000175000001440000000421111243310677015600 00000000000000/* -*- linux-c -*- Copyright (C) 2005 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: dec_vorbis.h 1068 2009-07-24 12:02:30Z peterszilagyi $ */ #ifndef _DEC_VORBIS_H #define _DEC_VORBIS_H #ifdef HAVE_OGG_VORBIS #ifdef _WIN32 #undef _WIN32 #include #define _WIN32 #else #include #endif /* _WIN32 */ #endif /* HAVE_OGG_VORBIS */ #include "../httpc.h" #include "file_decoder.h" /* Decoding buffer size for Vorbis */ #define VORBIS_BUFSIZE 4096 /* size of ringbuffer for decoded Vorbis data (in frames) */ #define RB_VORBIS_SIZE 262144 #ifdef HAVE_OGG_VORBIS typedef struct _vorbis_pdata_t { rb_t * rb; FILE * vorbis_file; OggVorbis_File vf; vorbis_info * vi; int is_eos; http_session_t * session; } vorbis_pdata_t; #endif /* HAVE_OGG_VORBIS */ decoder_t * vorbis_decoder_init(file_decoder_t * fdec); #ifdef HAVE_OGG_VORBIS void vorbis_decoder_destroy(decoder_t * dec); int vorbis_decoder_open(decoder_t * dec, char * filename); void vorbis_decoder_send_metadata(decoder_t * dec); int vorbis_stream_decoder_open(decoder_t * dec, http_session_t * session); void vorbis_decoder_close(decoder_t * dec); unsigned int vorbis_decoder_read(decoder_t * dec, float * dest, int num); void vorbis_decoder_seek(decoder_t * dec, unsigned long long seek_to_pos); #endif /* HAVE_OGG_VORBIS */ #endif /* _DEC_VORBIS_H */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/decoder/dec_vorbis.c0000644000175000001440000002320711243310677015601 00000000000000/* -*- linux-c -*- Copyright (C) 2005 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: dec_vorbis.c 1068 2009-07-24 12:02:30Z peterszilagyi $ */ #include #include #include #include #include #include "../metadata_ogg.h" #include "dec_vorbis.h" extern size_t sample_size; #ifdef HAVE_OGG_VORBIS /* void dump_vc(vorbis_comment * vc) { int i; if (!vc) { printf("vc = NULL\n"); return; } for (i = 0; i < vc->comments; i++) { printf("[%d] %s\n", i, vc->user_comments[i]); } printf("[V] %s\n", vc->vendor); } */ int vorbis_write_metadata(file_decoder_t * fdec, metadata_t * meta) { GSList * slist; int n_pages; unsigned char * payload; unsigned int length; slist = meta_ogg_parse(fdec->filename); payload = meta_ogg_vc_render(meta, &length); if (payload == NULL) { return META_ERROR_INTERNAL; } slist = meta_ogg_vc_encapsulate_payload(slist, &payload, length, &n_pages); if (meta_ogg_render(slist, fdec->filename, n_pages) < 0) { meta_ogg_free(slist); free(payload); return META_ERROR_NOT_WRITABLE; } meta_ogg_free(slist); free(payload); return META_ERROR_NONE; } void vorbis_send_metadata(file_decoder_t * fdec, vorbis_pdata_t * pd) { vorbis_comment * vc = ov_comment(&pd->vf, -1); metadata_t * meta = metadata_from_vorbis_comment(vc); if (fdec->is_stream) { meta->writable = 0; } else { if (access(fdec->filename, R_OK | W_OK) == 0) { meta->writable = 1; fdec->meta_write = vorbis_write_metadata; } else { meta->writable = 0; } } if (fdec->is_stream) { httpc_add_headers_meta(pd->session, meta); } meta->fdec = fdec; fdec->meta = meta; } /* return 1 if reached end of stream, 0 else */ int decode_vorbis(decoder_t * dec) { vorbis_pdata_t * pd = (vorbis_pdata_t *)dec->pdata; file_decoder_t * fdec = dec->fdec; int i; long bytes_read; float fbuffer[VORBIS_BUFSIZE/2]; char buffer[VORBIS_BUFSIZE]; int current_section; bytes_read = ov_read(&(pd->vf), buffer, VORBIS_BUFSIZE, bigendianp(), 2, 1, ¤t_section); switch (bytes_read) { case 0: /* end of file */ return 1; break; case OV_HOLE: if (fdec->is_stream) { vorbis_send_metadata(fdec, pd); break; } else { printf("dec_vorbis.c/decode_vorbis(): ov_read() returned OV_HOLE\n"); printf("This indicates an interruption in the Vorbis data (one of:\n"); printf("garbage between Ogg pages, loss of sync, or corrupt page).\n"); } break; case OV_EBADLINK: printf("dec_vorbis.c/decode_vorbis(): ov_read() returned OV_EBADLINK\n"); printf("An invalid stream section was supplied to libvorbisfile.\n"); break; default: for (i = 0; i < bytes_read/2; i++) { fbuffer[i] = *((short *)(buffer + 2*i)) * fdec->voladj_lin / 32768.f; } rb_write(pd->rb, (char *)fbuffer, bytes_read/2 * sample_size); break; } return 0; } decoder_t * vorbis_decoder_init(file_decoder_t * fdec) { decoder_t * dec = NULL; if ((dec = calloc(1, sizeof(decoder_t))) == NULL) { fprintf(stderr, "dec_vorbis.c: vorbis_decoder_new() failed: calloc error\n"); return NULL; } dec->fdec = fdec; if ((dec->pdata = calloc(1, sizeof(vorbis_pdata_t))) == NULL) { fprintf(stderr, "dec_vorbis.c: vorbis_decoder_new() failed: calloc error\n"); return NULL; } dec->init = vorbis_decoder_init; dec->destroy = vorbis_decoder_destroy; dec->open = vorbis_decoder_open; dec->send_metadata = vorbis_decoder_send_metadata; dec->close = vorbis_decoder_close; dec->read = vorbis_decoder_read; dec->seek = vorbis_decoder_seek; return dec; } void vorbis_decoder_destroy(decoder_t * dec) { free(dec->pdata); free(dec); } size_t read_vorbis_stream(void *ptr, size_t size, size_t nmemb, void * datasource) { http_session_t * session = (http_session_t *) datasource; return httpc_read(session, (char *)ptr, size*nmemb); } int seek_vorbis_stream(void * datasource, ogg_int64_t offset, int whence) { http_session_t * session = (http_session_t *) datasource; if (session->type != HTTPC_SESSION_NORMAL) return -1; /* HTTP stream is not seekable */ return httpc_seek(session, offset, whence); } long tell_vorbis_stream(void * datasource) { http_session_t * session = (http_session_t *) datasource; return httpc_tell(session); } int close_vorbis_stream(void * datasource) { http_session_t * session = (http_session_t *) datasource; session->fdec->is_stream = 0; httpc_close(session); httpc_del(session); return 0; } void pause_vorbis_stream(decoder_t * dec) { vorbis_pdata_t * pd = (vorbis_pdata_t *)dec->pdata; char flush_dest; httpc_close(pd->session); if (pd->session->type == HTTPC_SESSION_STREAM) { /* empty vorbis decoder ringbuffer */ while (rb_read_space(pd->rb)) rb_read(pd->rb, &flush_dest, sizeof(char)); } } void resume_vorbis_stream(decoder_t * dec) { vorbis_pdata_t * pd = (vorbis_pdata_t *)dec->pdata; httpc_reconnect(pd->session); } int vorbis_decoder_finish_open(decoder_t * dec) { vorbis_pdata_t * pd = (vorbis_pdata_t *)dec->pdata; file_decoder_t * fdec = dec->fdec; pd->vi = ov_info(&(pd->vf), -1); if ((pd->vi->channels != 1) && (pd->vi->channels != 2)) { fprintf(stderr, "vorbis_decoder_open: Ogg Vorbis file with %d channels " "is unsupported\n", pd->vi->channels); return DECODER_OPEN_FERROR; } if (ov_streams(&(pd->vf)) != 1) { fprintf(stderr, "vorbis_decoder_open: This Ogg Vorbis file contains " "multiple logical streams.\n" "Currently such a file is not supported.\n"); return DECODER_OPEN_FERROR; } pd->is_eos = 0; pd->rb = rb_create(pd->vi->channels * sample_size * RB_VORBIS_SIZE); fdec->fileinfo.channels = pd->vi->channels; fdec->fileinfo.sample_rate = pd->vi->rate; if (fdec->is_stream && pd->session->type != HTTPC_SESSION_NORMAL) { fdec->fileinfo.total_samples = 0; } else { fdec->fileinfo.total_samples = ov_pcm_total(&(pd->vf), -1); } fdec->fileinfo.bps = ov_bitrate(&(pd->vf), -1); fdec->file_lib = VORBIS_LIB; strcpy(dec->format_str, "Ogg Vorbis"); vorbis_send_metadata(fdec, pd); return DECODER_OPEN_SUCCESS; } int vorbis_stream_decoder_open(decoder_t * dec, http_session_t * session) { vorbis_pdata_t * pd = (vorbis_pdata_t *)dec->pdata; file_decoder_t * fdec = dec->fdec; ov_callbacks ov_cb; ov_cb.read_func = read_vorbis_stream; ov_cb.seek_func = seek_vorbis_stream; ov_cb.close_func = close_vorbis_stream; ov_cb.tell_func = tell_vorbis_stream; if (ov_open_callbacks((void *)session, &(pd->vf), NULL, 0, ov_cb) != 0) { /* not an Ogg Vorbis stream */ return DECODER_OPEN_BADLIB; } fdec->is_stream = 1; pd->session = session; dec->pause = pause_vorbis_stream; dec->resume = resume_vorbis_stream; return vorbis_decoder_finish_open(dec); } int vorbis_decoder_open(decoder_t * dec, char * filename) { vorbis_pdata_t * pd = (vorbis_pdata_t *)dec->pdata; file_decoder_t * fdec = dec->fdec; if ((pd->vorbis_file = fopen(filename, "rb")) == NULL) { fprintf(stderr, "vorbis_decoder_open: fopen() failed\n"); return DECODER_OPEN_FERROR; } if (ov_open(pd->vorbis_file, &(pd->vf), NULL, 0) != 0) { /* not an Ogg Vorbis file */ fclose(pd->vorbis_file); return DECODER_OPEN_BADLIB; } fdec->is_stream = 0; return vorbis_decoder_finish_open(dec); } void vorbis_decoder_send_metadata(decoder_t * dec ) { file_decoder_t * fdec = dec->fdec; if (fdec->meta != NULL && fdec->meta_cb != NULL) { fdec->meta_cb(fdec->meta, fdec->meta_cbdata); } } void vorbis_decoder_close(decoder_t * dec) { vorbis_pdata_t * pd = (vorbis_pdata_t *)dec->pdata; ov_clear(&(pd->vf)); rb_free(pd->rb); } unsigned int vorbis_decoder_read(decoder_t * dec, float * dest, int num) { vorbis_pdata_t * pd = (vorbis_pdata_t *)dec->pdata; unsigned int numread = 0; unsigned int n_avail = 0; while ((rb_read_space(pd->rb) < num * pd->vi->channels * sample_size) && (!pd->is_eos)) { pd->is_eos = decode_vorbis(dec); } n_avail = rb_read_space(pd->rb) / (pd->vi->channels * sample_size); if (n_avail > num) n_avail = num; rb_read(pd->rb, (char *)dest, n_avail * pd->vi->channels * sample_size); numread = n_avail; return numread; } void vorbis_decoder_seek(decoder_t * dec, unsigned long long seek_to_pos) { vorbis_pdata_t * pd = (vorbis_pdata_t *)dec->pdata; file_decoder_t * fdec = dec->fdec; char flush_dest; if (fdec->is_stream && pd->session->type != HTTPC_SESSION_NORMAL) return; if (ov_pcm_seek(&(pd->vf), seek_to_pos) == 0) { fdec->samples_left = fdec->fileinfo.total_samples - seek_to_pos; /* empty vorbis decoder ringbuffer */ while (rb_read_space(pd->rb)) rb_read(pd->rb, &flush_dest, sizeof(char)); } else { fprintf(stderr, "vorbis_decoder_seek: warning: ov_pcm_seek() failed\n"); } } #else decoder_t * vorbis_decoder_init(file_decoder_t * fdec) { return NULL; } #endif /* HAVE_OGG_VORBIS */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/decoder/dec_wavpack.h0000644000175000001440000000341311243310677015733 00000000000000/* -*- linux-c -*- Copyright (C) 2007 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: dec_wavpack.h 1068 2009-07-24 12:02:30Z peterszilagyi $ */ #ifndef _DEC_WAVPACK_H #define _DEC_WAVPACK_H #include "file_decoder.h" #ifdef HAVE_WAVPACK #include #define RB_WAVPACK_SIZE 262144 #define WAVPACK_BUFSIZE 4096 typedef struct _wavpack_pdata_t { WavpackContext *wpc; rb_t * rb; int flags; char error[100]; int last_decoded_samples; int bits_per_sample; int end_of_file; float scale_factor_float; } wavpack_pdata_t; void wavpack_decoder_destroy(decoder_t * dec); int wavpack_decoder_open(decoder_t * dec, char * filename); void wavpack_decoder_send_metadata(decoder_t * dec); void wavpack_decoder_close(decoder_t * dec); unsigned int wavpack_decoder_read(decoder_t * dec, float * dest, int num); void wavpack_decoder_seek(decoder_t * dec, unsigned long long seek_to_pos); #endif /* HAVE_WAVPACK */ decoder_t * wavpack_decoder_init(file_decoder_t * fdec); #endif /* _DEC_WAVPACK_H */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/decoder/dec_wavpack.c0000644000175000001440000001474211243310677015735 00000000000000/* -*- linux-c -*- Copyright (C) 2007 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: dec_wavpack.c 1068 2009-07-24 12:02:30Z peterszilagyi $ */ #include #include #include #include #include #include "../metadata_ape.h" #include "dec_wavpack.h" extern size_t sample_size; #ifdef HAVE_WAVPACK int decode_wavpack(decoder_t * dec) { file_decoder_t * fdec = dec->fdec; wavpack_pdata_t * pd = (wavpack_pdata_t *)dec->pdata; int32_t buffer[WAVPACK_BUFSIZE]; uint i, j; float fval[fdec->fileinfo.channels]; pd->last_decoded_samples = WavpackUnpackSamples(pd->wpc, buffer, WAVPACK_BUFSIZE / fdec->fileinfo.channels); /* Actual floating point data is output into an integer, will have to deal with that */ if (WavpackGetMode (pd->wpc) & MODE_FLOAT) { int num_samples = pd->last_decoded_samples * fdec->fileinfo.channels; int32_t * buffer_pointer = buffer; while (num_samples--) { float data = * (float*) buffer_pointer; data *= pd->scale_factor_float; if (data > pd->scale_factor_float) data = pd->scale_factor_float; if (data < -(pd->scale_factor_float)) data = -(pd->scale_factor_float); *buffer_pointer++ = (int32_t) data; } } if (pd->last_decoded_samples == 0) return 1; for (i = 0; i < pd->last_decoded_samples * fdec->fileinfo.channels; i += fdec->fileinfo.channels) { for (j = 0; j < fdec->fileinfo.channels; j++) { fval[j] = buffer[i+j] * fdec->voladj_lin / pd->scale_factor_float; if (fval[j] < -1.0f) { fval[j] = -1.0f; } else if (fval[j] > 1.0f) { fval[j] = 1.0f; } } rb_write(pd->rb, (char *)fval, fdec->fileinfo.channels * sample_size); } return 0; } decoder_t * wavpack_decoder_init(file_decoder_t * fdec) { decoder_t * dec = NULL; if ((dec = calloc(1, sizeof(decoder_t))) == NULL) { fprintf(stderr, "dec_wavpack.c: wavpack_decoder_new() failed: calloc error\n"); return NULL; } dec->fdec = fdec; if ((dec->pdata = calloc(1, sizeof(wavpack_pdata_t))) == NULL) { fprintf(stderr, "dec_wavpack.c: wavpack_decoder_new() failed: calloc error\n"); return NULL; } dec->init = wavpack_decoder_init; dec->destroy = wavpack_decoder_destroy; dec->open = wavpack_decoder_open; dec->send_metadata = wavpack_decoder_send_metadata; dec->close = wavpack_decoder_close; dec->read = wavpack_decoder_read; dec->seek = wavpack_decoder_seek; return dec; } void wavpack_decoder_destroy(decoder_t * dec) { free(dec->pdata); free(dec); } int wavpack_decoder_open(decoder_t * dec, char * filename) { file_decoder_t * fdec = dec->fdec; wavpack_pdata_t * pd = (wavpack_pdata_t *)dec->pdata; int i, corrected_bits_per_sample; metadata_t * meta; /* More than 2 channels doesn't work */ /* Normalize is for floating point data only, it gets scaled to -1.0 and 1.0, not replaygain related or anything */ /* Opening hybrid correction file if possible */ pd->flags = OPEN_2CH_MAX | OPEN_TAGS | OPEN_NORMALIZE | OPEN_WVC; strcpy(pd->error, "No Error"); pd->wpc = WavpackOpenFileInput(filename, pd->error, pd->flags, 0); /* The decoder can actually do something with the file */ if (pd->wpc != NULL) { fdec->fileinfo.channels = WavpackGetReducedChannels(pd->wpc); fdec->fileinfo.sample_rate = WavpackGetSampleRate(pd->wpc); fdec->fileinfo.total_samples = WavpackGetNumSamples(pd->wpc); fdec->fileinfo.bps = WavpackGetBitsPerSample(pd->wpc) * fdec->fileinfo.sample_rate * fdec->fileinfo.channels; pd->bits_per_sample = WavpackGetBitsPerSample(pd->wpc); pd->rb = rb_create(fdec->fileinfo.channels * sample_size * RB_WAVPACK_SIZE); pd->end_of_file = 0; /* It's best to calculate the scale factor in advance and store it */ pd->scale_factor_float = 1; /* Anything other than 8, 16, 24 or 32 bits is padded to the nearest one */ if (WavpackGetMode (pd->wpc) & MODE_FLOAT) { corrected_bits_per_sample = 32; } else { corrected_bits_per_sample = ceil(pd->bits_per_sample/8.0f) * 8; } for (i = 1; i < corrected_bits_per_sample; i++) { pd->scale_factor_float *= 2; } strcpy(dec->format_str, "WavPack"); fdec->file_lib = WAVPACK_LIB; meta = metadata_new(); meta_ape_send_metadata(meta, fdec); return DECODER_OPEN_SUCCESS; } return DECODER_OPEN_BADLIB; } void wavpack_decoder_send_metadata(decoder_t * dec) { } void wavpack_decoder_close(decoder_t * dec) { wavpack_pdata_t * pd = (wavpack_pdata_t *)dec->pdata; WavpackCloseFile(pd->wpc); rb_free(pd->rb); } unsigned int wavpack_decoder_read(decoder_t * dec, float * dest, int num) { file_decoder_t * fdec = dec->fdec; wavpack_pdata_t * pd = (wavpack_pdata_t *)dec->pdata; while ((rb_read_space(pd->rb) < num * fdec->fileinfo.channels * sample_size) && (pd->end_of_file == 0)) { pd->end_of_file = decode_wavpack(dec); } uint actual_num = 0; uint n_avail = rb_read_space(pd->rb) / (fdec->fileinfo.channels * sample_size); if ( num > n_avail ) { actual_num = n_avail; } else { actual_num = num; } rb_read(pd->rb, (char *)dest, actual_num * sample_size * fdec->fileinfo.channels); return actual_num; } void wavpack_decoder_seek(decoder_t * dec, unsigned long long seek_to_pos) { file_decoder_t * fdec = dec->fdec; wavpack_pdata_t * pd = (wavpack_pdata_t *)dec->pdata; char flush_dest; if (WavpackSeekSample(pd->wpc, seek_to_pos) == 1) { fdec->samples_left = fdec->fileinfo.total_samples - seek_to_pos; /* Empty ringbuffer */ while (rb_read_space(pd->rb)) rb_read(pd->rb, &flush_dest, sizeof(char)); } else { fprintf(stderr, "wavpack_decoder_seek: warning: WavpackSeekSample() failed\n"); } } #else decoder_t * wavpack_decoder_init(file_decoder_t * fdec) { return NULL; } #endif /* HAVE_WAVPACK */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/decoder/file_decoder.h0000644000175000001440000001073711243310677016077 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: file_decoder.h 1068 2009-07-24 12:02:30Z peterszilagyi $ */ #ifndef _FILE_DECODER_H #define _FILE_DECODER_H #include "../common.h" #include "../options.h" #include "../metadata.h" #include "../metadata_api.h" #include "../rb.h" #ifdef __cplusplus extern "C" { #endif /* input libs */ #define NULL_LIB 0 #define CDDA_LIB 1 #define SNDFILE_LIB 2 #define FLAC_LIB 3 #define VORBIS_LIB 4 #define SPEEX_LIB 5 #define MPC_LIB 6 #define MAD_LIB 7 #define MOD_LIB 8 #define MAC_LIB 9 #define LAVC_LIB 10 #define WAVPACK_LIB 11 #define N_DECODERS 12 /* format_flags */ #define FORMAT_VBR 0x0001 #define FORMAT_UBR 0x0002 typedef struct _fileinfo_t { unsigned long long total_samples; unsigned long sample_rate; int channels; int is_mono; int bps; char * format_str; /* buffer allocated in pdec */ int format_flags; } fileinfo_t; typedef struct _file_decoder_t { /* public */ char * filename; int file_open; int file_lib; fileinfo_t fileinfo; unsigned long long sample_pos; /* used w/unknown length files only */ unsigned long long samples_left; float voladj_db; float voladj_lin; int is_stream; /* Note that the metadata block sent by meta_cb is still owned by the file_decoder instance and should not be freed externally. However, it can be modified and 'if (meta->writable)', it can be written back to file by calling meta_write(). */ metadata_t * meta; void (* meta_cb)(metadata_t *, void *); void * meta_cbdata; /* meta_write() returns one of META_ERROR_*, defined in metadata_api.h */ int (* meta_write)(struct _file_decoder_t *, metadata_t *); /* private */ void * pdec; /* actually, it's (decoder_t *) */ } file_decoder_t; typedef struct _decoder_t { file_decoder_t * fdec; void * pdata; /* opaque pointer to decoder-dependent struct */ struct _decoder_t * (* init)(file_decoder_t * fdec); void (* destroy)(struct _decoder_t * dec); int (* open)(struct _decoder_t * dec, char * filename); void (* send_metadata)(struct _decoder_t * dec); void (* set_rva)(struct _decoder_t * dec, float voladj); void (* close)(struct _decoder_t * dec); unsigned int (* read)(struct _decoder_t * dec, float * dest, int num); void (* seek)(struct _decoder_t * dec, unsigned long long seek_to_pos); /* optional callbacks for stream decoders */ void (* pause)(struct _decoder_t * dec); void (* resume)(struct _decoder_t * dec); char format_str[MAXLEN]; int format_flags; } decoder_t; /* return values from decoder_t.open() -- see dec_null.c for explanation */ #define DECODER_OPEN_SUCCESS 0 #define DECODER_OPEN_BADLIB 1 #define DECODER_OPEN_FERROR 2 int is_valid_extension(char ** valid_extensions, char * filename, int module); void file_decoder_init(void); file_decoder_t * file_decoder_new(void); void file_decoder_delete(file_decoder_t * fdec); int file_decoder_open(file_decoder_t * fdec, char * filename); void file_decoder_send_metadata(file_decoder_t * fdec); void file_decoder_set_rva(file_decoder_t * fdec, float voladj); void file_decoder_set_meta_cb(file_decoder_t * fdec, void (* meta_cb)(metadata_t * meta, void * data), void * data); void file_decoder_close(file_decoder_t * fdec); unsigned int file_decoder_read(file_decoder_t * fdec, float * dest, int num); void file_decoder_seek(file_decoder_t * fdec, unsigned long long seek_to_pos); void file_decoder_pause(file_decoder_t * fdec); void file_decoder_resume(file_decoder_t * fdec); float get_file_duration(char * file); int bigendianp(void); #define db2lin(x) ((x) > -90.0f ? powf(10.0f, (x) * 0.05f) : 0.0f) #ifdef __cplusplus } /* extern "C" */ #endif #endif /* _FILE_DECODER_H */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/decoder/file_decoder.c0000644000175000001440000002520311253161434016060 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: file_decoder.c 1079 2009-09-04 19:40:39Z tszilagyi $ */ #include #include #include #include #include #include #include #include #include #include #include #ifdef _WIN32 #include #else #include #endif /* _WIN32 */ #include "file_decoder.h" #include "dec_null.h" #include "dec_cdda.h" #include "dec_sndfile.h" #include "dec_flac.h" #include "dec_vorbis.h" #include "dec_speex.h" #include "dec_mpc.h" #include "dec_mpeg.h" #include "dec_mod.h" #include "dec_mac.h" #include "dec_lavc.h" #include "dec_wavpack.h" extern size_t sample_size; extern options_t options; typedef decoder_t * decoder_init_t(file_decoder_t * fdec); /* this controls the order in which decoders are probed for a file */ decoder_init_t * decoder_init_v[N_DECODERS] = { null_decoder_init, cdda_decoder_init, sndfile_decoder_init, flac_decoder_init, vorbis_decoder_init, speex_dec_init, mpc_decoder_init_func, mac_decoder_init, mpeg_decoder_init, wavpack_decoder_init, mod_decoder_init, lavc_decoder_init }; /* utility function used by some decoders to check file extension */ int is_valid_extension(char ** valid_extensions, char * filename, int module) { int i; char * c = NULL, * d = NULL; char *ext; /* post ext */ i = 0; if ((c = strrchr(filename, '.')) != NULL) { ++c; while (valid_extensions[i] != NULL) { if (strcasecmp(c, valid_extensions[i]) == 0) { return 1; } ++i; } } if (module) { /* checking mod pre file extension */ /* lots of amiga modules has EXT.NAME filename format */ /* pre ext */ i = 0; ext = strdup(filename); if (ext && (c = strrchr(ext, '/')) != NULL) { ++c; if ((d = strchr(ext, '.')) != NULL) { *d = '\0'; while (valid_extensions[i] != NULL) { if (strcasecmp(c, valid_extensions[i]) == 0) { free(ext); return 1; } ++i; } } } free(ext); } return 0; } /* call this first before using file_decoder in program */ void file_decoder_init(void) { #ifdef HAVE_LAVC av_register_all(); #endif /* HAVE_LAVC */ } file_decoder_t * file_decoder_new(void) { file_decoder_t * fdec = NULL; if ((fdec = calloc(1, sizeof(file_decoder_t))) == NULL) { fprintf(stderr, "file_decoder.c: file_decoder_new() failed: calloc error\n"); return NULL; } fdec->file_open = 0; fdec->voladj_db = 0.0f; fdec->voladj_lin = 1.0f; fdec->pdec = NULL; return fdec; } void file_decoder_delete(file_decoder_t * fdec) { if (fdec->file_open) { file_decoder_close(fdec); } free(fdec); } int file_decoder_finalize_open(file_decoder_t * fdec, decoder_t * dec, char * filename) { if (fdec->fileinfo.channels == 1) { fdec->fileinfo.is_mono = 1; goto ok_open; } else if (fdec->fileinfo.channels == 2) { fdec->fileinfo.is_mono = 0; goto ok_open; } else { fprintf(stderr, "file_decoder_open: programmer error: " "soundfile with %d\n channels is unsupported.\n", fdec->fileinfo.channels); goto no_open; } ok_open: fdec->file_open = 1; fdec->samples_left = fdec->fileinfo.total_samples; fdec->fileinfo.format_str = dec->format_str; fdec->fileinfo.format_flags = dec->format_flags; return 0; no_open: fprintf(stderr, "file_decoder_open: unable to open %s\n", filename); return 1; } int stream_decoder_open(file_decoder_t * fdec, char * URL) { int ret; decoder_t * dec; http_session_t * session = httpc_new(); if ((ret = httpc_init(session, fdec, URL, options.inet_use_proxy, options.inet_proxy, options.inet_proxy_port, options.inet_noproxy_domains, 0L)) != HTTPC_OK) { fprintf(stderr, "stream_decoder_open: httpc_init failed, ret = %d\n", ret); httpc_del(session); return DECODER_OPEN_FERROR; } #ifdef HAVE_MPEG if ((session->headers.content_type == NULL) || (strcasecmp(session->headers.content_type, "audio/mp3") == 0) || (strcasecmp(session->headers.content_type, "audio/mpeg") == 0) || (strcasecmp(session->headers.content_type, "application/mp3") == 0) || (strcasecmp(session->headers.content_type, "application/mpeg") == 0)) { int ret; if (session->headers.content_type == NULL) { fprintf(stderr, "Warning: no Content-Type, assuming audio/mpeg\n"); } dec = mpeg_decoder_init(fdec); if (!dec) return DECODER_OPEN_FERROR; ret = mpeg_stream_decoder_open(dec, session); if (ret == DECODER_OPEN_FERROR) { dec->destroy(dec); return ret; } fdec->pdec = (void *)dec; return file_decoder_finalize_open(fdec, dec, URL); } #else if (session->headers.content_type == NULL) { fprintf(stderr, "stream_decoder_open: error: no Content-Type found\n"); httpc_close(session); httpc_del(session); return DECODER_OPEN_FERROR; } #endif /* HAVE_MPEG */ #ifdef HAVE_OGG_VORBIS if ((strcasecmp(session->headers.content_type, "application/ogg") == 0) || (strcasecmp(session->headers.content_type, "audio/x-vorbis") == 0)) { int ret; dec = vorbis_decoder_init(fdec); if (!dec) return DECODER_OPEN_FERROR; ret = vorbis_stream_decoder_open(dec, session); if (ret == DECODER_OPEN_FERROR) { dec->destroy(dec); return ret; } fdec->pdec = (void *)dec; return file_decoder_finalize_open(fdec, dec, URL); } #endif /* HAVE_OGG_VORBIS */ fprintf(stderr, "Sorry, no handler for Content-Type: %s\n", session->headers.content_type); httpc_close(session); httpc_del(session); return 1; } /* return: 0 is OK, >0 is error */ int file_decoder_open(file_decoder_t * fdec, char * filename) { int i, ret; decoder_t * dec; if (filename == NULL) { fprintf(stderr, "Warning: filename == NULL passed to file_decoder_open()\n"); fprintf(stderr, "This is likely to be a programmer error, please report.\n"); return 1; } fdec->filename = strdup(filename); if (httpc_is_url(filename)) return stream_decoder_open(fdec, filename); for (i = 0; i < N_DECODERS; i++) { dec = decoder_init_v[i](fdec); if (!dec) { continue; } fdec->pdec = (void *)dec; ret = dec->open(dec, filename); if (ret == DECODER_OPEN_FERROR) { dec->destroy(dec); goto no_open; } else if (ret == DECODER_OPEN_BADLIB) { dec->destroy(dec); continue; } else if (ret != DECODER_OPEN_SUCCESS) { printf("programmer error, please report: " "illegal retvalue %d from dec->open() at %d\n", ret, i); return 1; } break; } if (i == N_DECODERS) { goto no_open; } if (fdec->fileinfo.channels == 1) { fdec->fileinfo.is_mono = 1; goto ok_open; } else if (fdec->fileinfo.channels == 2) { fdec->fileinfo.is_mono = 0; goto ok_open; } else { fprintf(stderr, "file_decoder_open: programmer error: " "soundfile with %d\n channels is unsupported.\n", fdec->fileinfo.channels); goto no_open; } ok_open: fdec->file_open = 1; fdec->samples_left = fdec->fileinfo.total_samples; fdec->fileinfo.format_str = dec->format_str; fdec->fileinfo.format_flags = dec->format_flags; return 0; no_open: fprintf(stderr, "file_decoder_open: unable to open %s\n", filename); return 1; } void file_decoder_send_metadata(file_decoder_t * fdec) { decoder_t * dec = (decoder_t *)(fdec->pdec); return dec->send_metadata(dec); } void file_decoder_set_rva(file_decoder_t * fdec, float voladj) { fdec->voladj_db = voladj; fdec->voladj_lin = db2lin(voladj); } void file_decoder_set_meta_cb(file_decoder_t * fdec, void (* meta_cb)(metadata_t * meta, void * data), void * data) { fdec->meta_cb = meta_cb; fdec->meta_cbdata = data; } void file_decoder_close(file_decoder_t * fdec) { decoder_t * dec; if (!fdec->file_open) { return; } dec = (decoder_t *)(fdec->pdec); dec->close(dec); dec->destroy(dec); fdec->pdec = NULL; fdec->file_open = 0; fdec->file_lib = 0; if (fdec->filename != NULL) { free(fdec->filename); fdec->filename = NULL; } if (fdec->meta != NULL) { metadata_free(fdec->meta); fdec->meta = NULL; } } unsigned int file_decoder_read(file_decoder_t * fdec, float * dest, int num) { decoder_t * dec = (decoder_t *)(fdec->pdec); return dec->read(dec, dest, num); } void file_decoder_seek(file_decoder_t * fdec, unsigned long long seek_to_pos) { decoder_t * dec = (decoder_t *)(fdec->pdec); dec->seek(dec, seek_to_pos); } void file_decoder_pause(file_decoder_t * fdec) { decoder_t * dec = (decoder_t *)(fdec->pdec); if (dec->pause != NULL) dec->pause(dec); } void file_decoder_resume(file_decoder_t * fdec) { decoder_t * dec = (decoder_t *)(fdec->pdec); if (dec->resume != NULL) dec->resume(dec); } float get_file_duration(char * file) { file_decoder_t * fdec; float duration; if ((fdec = file_decoder_new()) == NULL) { fprintf(stderr, "get_file_duration: error: file_decoder_new() returned NULL\n"); return -1.0f; } if (file_decoder_open(fdec, file)) { fprintf(stderr, "file_decoder_open() failed on %s\n", file); file_decoder_delete(fdec); return -1.0f; } duration = (float)fdec->fileinfo.total_samples / fdec->fileinfo.sample_rate; file_decoder_close(fdec); file_decoder_delete(fdec); return duration; } /* taken from cdparanoia source */ int bigendianp(void) { int test=1; char *hack=(char *)(&test); if(hack[0])return(0); return(1); } // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/encoder/0000777000175000001440000000000011331334363013404 500000000000000aqualung-0.9beta11/src/encoder/Makefile.am0000644000175000001440000000030210612341731015345 00000000000000noinst_LIBRARIES = libencoder.a libencoder_a_SOURCES = \ enc_flac.h enc_flac.c \ enc_lame.h enc_lame.c \ enc_sndfile.h enc_sndfile.c \ enc_vorbis.h enc_vorbis.c \ file_encoder.h file_encoder.c aqualung-0.9beta11/src/encoder/Makefile.in0000644000175000001440000003043411331334253015367 00000000000000# Makefile.in generated by automake 1.10.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # This Makefile.in 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. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = src/encoder DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = LIBRARIES = $(noinst_LIBRARIES) AR = ar ARFLAGS = cru libencoder_a_AR = $(AR) $(ARFLAGS) libencoder_a_LIBADD = am_libencoder_a_OBJECTS = enc_flac.$(OBJEXT) enc_lame.$(OBJEXT) \ enc_sndfile.$(OBJEXT) enc_vorbis.$(OBJEXT) \ file_encoder.$(OBJEXT) libencoder_a_OBJECTS = $(am_libencoder_a_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(libencoder_a_SOURCES) DIST_SOURCES = $(libencoder_a_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBAVCODEC_CFLAGS = @LIBAVCODEC_CFLAGS@ LIBAVCODEC_LIBS = @LIBAVCODEC_LIBS@ LIBAVFORMAT_CFLAGS = @LIBAVFORMAT_CFLAGS@ LIBAVFORMAT_LIBS = @LIBAVFORMAT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ var = @var@ noinst_LIBRARIES = libencoder.a libencoder_a_SOURCES = \ enc_flac.h enc_flac.c \ enc_lame.h enc_lame.c \ enc_sndfile.h enc_sndfile.c \ enc_vorbis.h enc_vorbis.c \ file_encoder.h file_encoder.c all: all-am .SUFFIXES: .SUFFIXES: .c .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/encoder/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/encoder/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) libencoder.a: $(libencoder_a_OBJECTS) $(libencoder_a_DEPENDENCIES) -rm -f libencoder.a $(libencoder_a_AR) libencoder.a $(libencoder_a_OBJECTS) $(libencoder_a_LIBADD) $(RANLIB) libencoder.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enc_flac.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enc_lame.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enc_sndfile.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enc_vorbis.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file_encoder.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-exec-am: install-html: install-html-am install-info: install-info-am install-man: install-pdf: install-pdf-am install-ps: install-ps-am installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-noinstLIBRARIES ctags distclean distclean-compile \ distclean-generic distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: aqualung-0.9beta11/src/encoder/enc_flac.h0000644000175000001440000000361610612341731015227 00000000000000/* -*- linux-c -*- Copyright (C) 2005 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: enc_flac.h 509 2006-12-26 21:09:58Z tszilagyi $ */ #ifndef _ENC_FLAC_H #define _ENC_FLAC_H #include #ifdef HAVE_FLAC_8 #include #include #include #endif /* HAVE_FLAC_8 */ #ifdef HAVE_FLAC_7 #include #include #include #endif /* HAVE_FLAC_7 */ #include "file_encoder.h" #ifdef HAVE_FLAC typedef struct _flac_pencdata_t { #ifdef HAVE_FLAC_8 FLAC__StreamEncoder * encoder; #endif /* HAVE_FLAC_8 */ #ifdef HAVE_FLAC_7 FLAC__FileEncoder * encoder; #endif /* HAVE_FLAC_7 */ FLAC__int32 ** buf; int bufsize; int channels; encoder_mode_t mode; } flac_pencdata_t; #endif /* HAVE_FLAC */ encoder_t * flac_encoder_init(file_encoder_t * fenc); #ifdef HAVE_FLAC void flac_encoder_destroy(encoder_t * enc); int flac_encoder_open(encoder_t * enc, encoder_mode_t * mode); void flac_encoder_close(encoder_t * enc); unsigned int flac_encoder_write(encoder_t * enc, float * data, int num); #endif /* HAVE_FLAC */ #endif /* _ENC_FLAC_H */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/encoder/enc_flac.c0000644000175000001440000002204210722255570015223 00000000000000/* -*- linux-c -*- Copyright (C) 2005 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: enc_flac.c 893 2007-11-25 11:24:39Z tszilagyi $ */ #include #include #include #include #include "../i18n.h" #include "../metadata.h" #include "../metadata_flac.h" #include "enc_flac.h" #ifdef HAVE_FLAC #ifdef HAVE_FLAC_7 /* Compression level presets to match the interface * of the command-line flac 1.1.2 encoder. */ typedef struct { FLAC__bool ms; FLAC__bool ms_loose; int lpc_order; int blocksize; FLAC__bool exhaustive; int min_res; int max_res; } flac_preset_t; flac_preset_t flac_presets[] = { { false, false, 0, 1152, false, 2, 2 }, { false, true, 0, 1152, false, 2, 2 }, { true, false, 0, 1152, false, 0, 3 }, { false, false, 6, 4608, false, 3, 3 }, { false, true, 8, 4608, false, 3, 3 }, { true, false, 8, 4608, false, 3, 3 }, { true, false, 8, 4608, false, 0, 4 }, { true, false, 8, 4608, true, 0, 6 }, { true, false, 12, 4608, true, 0, 6 }, }; #endif /* HAVE_FLAC_7 */ encoder_t * flac_encoder_init(file_encoder_t * fenc) { encoder_t * enc = NULL; if ((enc = calloc(1, sizeof(encoder_t))) == NULL) { fprintf(stderr, "enc_flac.c: flac_encoder_new() failed: calloc error\n"); return NULL; } enc->fenc = fenc; if ((enc->pdata = calloc(1, sizeof(flac_pencdata_t))) == NULL) { fprintf(stderr, "enc_flac.c: flac_encoder_new() failed: calloc error\n"); return NULL; } enc->init = flac_encoder_init; enc->destroy = flac_encoder_destroy; enc->open = flac_encoder_open; enc->close = flac_encoder_close; enc->write = flac_encoder_write; return enc; } void flac_encoder_destroy(encoder_t * enc) { free(enc->pdata); free(enc); } int flac_encoder_open(encoder_t * enc, encoder_mode_t * mode) { flac_pencdata_t * pd = (flac_pencdata_t *)enc->pdata; int i; #ifdef HAVE_FLAC_8 FLAC__StreamEncoderInitStatus state; pd->encoder = FLAC__stream_encoder_new(); if (pd->encoder == NULL) return -1; FLAC__stream_encoder_set_bits_per_sample(pd->encoder, 16); FLAC__stream_encoder_set_channels(pd->encoder, mode->channels); FLAC__stream_encoder_set_sample_rate(pd->encoder, mode->sample_rate); FLAC__stream_encoder_set_verify(pd->encoder, true); FLAC__stream_encoder_set_compression_level(pd->encoder, mode->clevel); state = FLAC__stream_encoder_init_file(pd->encoder, mode->filename, NULL, NULL); if (state != FLAC__STREAM_ENCODER_INIT_STATUS_OK) { fprintf(stderr, "FLAC__stream_encoder_init_file returned error: %s\n", FLAC__StreamEncoderInitStatusString[state]); return -1; } #endif /* HAVE_FLAC_8 */ #ifdef HAVE_FLAC_7 FLAC__FileEncoderState state; pd->encoder = FLAC__file_encoder_new(); if (pd->encoder == NULL) return -1; FLAC__file_encoder_set_bits_per_sample(pd->encoder, 16); FLAC__file_encoder_set_channels(pd->encoder, mode->channels); FLAC__file_encoder_set_sample_rate(pd->encoder, mode->sample_rate); FLAC__file_encoder_set_verify(pd->encoder, true); if (mode->channels == 2) { FLAC__file_encoder_set_do_mid_side_stereo(pd->encoder, flac_presets[mode->clevel].ms); FLAC__file_encoder_set_loose_mid_side_stereo(pd->encoder, flac_presets[mode->clevel].ms_loose); } FLAC__file_encoder_set_max_lpc_order(pd->encoder, flac_presets[mode->clevel].lpc_order); FLAC__file_encoder_set_blocksize(pd->encoder, flac_presets[mode->clevel].blocksize); FLAC__file_encoder_set_do_exhaustive_model_search(pd->encoder, flac_presets[mode->clevel].exhaustive); FLAC__file_encoder_set_min_residual_partition_order(pd->encoder, flac_presets[mode->clevel].min_res); FLAC__file_encoder_set_max_residual_partition_order(pd->encoder, flac_presets[mode->clevel].max_res); FLAC__file_encoder_set_filename(pd->encoder, mode->filename); if ((state = FLAC__file_encoder_init(pd->encoder)) != FLAC__FILE_ENCODER_OK) { fprintf(stderr, "FLAC__file_encoder_init returned error: %s\n", FLAC__FileEncoderStateString[state]); return -1; } #endif /* HAVE_FLAC_7 */ pd->mode = *mode; pd->buf = (FLAC__int32 **)calloc(mode->channels, sizeof(FLAC__int32 *)); for (i = 0; i < mode->channels; i++) { pd->buf[i] = NULL; } pd->bufsize = 0; pd->channels = mode->channels; return 0; } unsigned int flac_encoder_write(encoder_t * enc, float * data, int num) { flac_pencdata_t * pd = (flac_pencdata_t *)enc->pdata; int i, n = 0; FLAC__bool b; if (pd->bufsize < num) { int k; for (k = 0; k < pd->channels; k++) { pd->buf[k] = realloc(pd->buf[k], num * sizeof(FLAC__int32)); } pd->bufsize = num; } for (i = 0; i < num; i++) { int k; for (k = 0; k < pd->channels; k++) { pd->buf[k][i] = data[n] * (1<<15); ++n; } } #ifdef HAVE_FLAC_8 b = FLAC__stream_encoder_process(pd->encoder, (const FLAC__int32 **)pd->buf, num); if (b != true) { fprintf(stderr, "FLAC__stream_encoder_process returned error: %s\n", FLAC__StreamEncoderStateString[FLAC__stream_encoder_get_state(pd->encoder)]); } #endif /* HAVE_FLAC_8 */ #ifdef HAVE_FLAC_7 b = FLAC__file_encoder_process(pd->encoder, (const FLAC__int32 **)pd->buf, num); if (b != true) { fprintf(stderr, "FLAC__file_encoder_process returned error: %s\n", FLAC__FileEncoderStateString[FLAC__file_encoder_get_state(pd->encoder)]); } #endif /* HAVE_FLAC_7 */ return num; } int flac_encoder_write_meta_vc(metadata_t * meta, FLAC__Metadata_SimpleIterator * iter) { int ret; FLAC__StreamMetadata * smeta = metadata_to_flac_streammeta(meta); if (FLAC__metadata_simple_iterator_get_block_type(iter) == FLAC__METADATA_TYPE_VORBIS_COMMENT) { ret = FLAC__metadata_simple_iterator_set_block(iter, smeta, true); if (ret == false) { fprintf(stderr, "error: FLAC metadata write failed!\n"); FLAC__metadata_simple_iterator_delete(iter); return -1; } } else { ret = FLAC__metadata_simple_iterator_insert_block_after(iter, smeta, true); if (ret == false) { fprintf(stderr, "error: FLAC metadata write failed!\n"); FLAC__metadata_object_delete(smeta); FLAC__metadata_simple_iterator_delete(iter); return -1; } } FLAC__metadata_object_delete(smeta); return 0; } #ifdef HAVE_FLAC_8 int flac_encoder_write_meta_pics(metadata_t * meta, FLAC__Metadata_SimpleIterator * iter) { meta_frame_t * frame = metadata_get_frame_by_tag(meta, META_TAG_FLAC_APIC, NULL); while (frame) { FLAC__StreamMetadata * smeta = metadata_apic_frame_to_smeta(frame); int ret = FLAC__metadata_simple_iterator_insert_block_after(iter, smeta, true); if (ret == false) { fprintf(stderr, "error: FLAC metadata write failed!\n"); FLAC__metadata_object_delete(smeta); FLAC__metadata_simple_iterator_delete(iter); return -1; } FLAC__metadata_object_delete(smeta); frame = metadata_get_frame_by_tag(meta, META_TAG_FLAC_APIC, frame); } return 0; } #endif /* HAVE_FLAC_8 */ void flac_encoder_write_meta(encoder_t * enc) { flac_pencdata_t * pd = (flac_pencdata_t *)enc->pdata; FLAC__Metadata_SimpleIterator * iter = FLAC__metadata_simple_iterator_new(); if (iter == NULL) return; if (FLAC__metadata_simple_iterator_init(iter, pd->mode.filename, false, false) != true) { fprintf(stderr, "FLAC__metadata_simple_iterator_init returned error: %s\n", FLAC__Metadata_SimpleIteratorStatusString[FLAC__metadata_simple_iterator_status(iter)]); FLAC__metadata_simple_iterator_delete(iter); return; } FLAC__metadata_simple_iterator_next(iter); if (metadata_get_frame_by_tag(enc->mode->meta, META_TAG_OXC, NULL) != NULL) { if (flac_encoder_write_meta_vc(enc->mode->meta, iter) < 0) { return; } } #ifdef HAVE_FLAC_8 if (flac_encoder_write_meta_pics(enc->mode->meta, iter) < 0) { return; } #endif /* HAVE_FLAC_8 */ FLAC__metadata_simple_iterator_delete(iter); } void flac_encoder_close(encoder_t * enc) { flac_pencdata_t * pd = (flac_pencdata_t *)enc->pdata; #ifdef HAVE_FLAC_8 FLAC__stream_encoder_finish(pd->encoder); FLAC__stream_encoder_delete(pd->encoder); #endif /* HAVE_FLAC_8 */ #ifdef HAVE_FLAC_7 FLAC__file_encoder_finish(pd->encoder); FLAC__file_encoder_delete(pd->encoder); #endif /* HAVE_FLAC_7 */ if (pd->bufsize > 0) { int k; for (k = 0; k < pd->channels; k++) { free(pd->buf[k]); } } free(pd->buf); if (pd->mode.write_meta) { flac_encoder_write_meta(enc); } } #else encoder_t * flac_encoder_init(file_encoder_t * fenc) { return NULL; } #endif /* HAVE_FLAC */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/encoder/enc_lame.h0000644000175000001440000000333310712325501015232 00000000000000/* -*- linux-c -*- Copyright (C) 2005 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: enc_lame.h 508 2006-12-26 16:31:56Z tszilagyi $ */ #ifndef _ENC_LAME_H #define _ENC_LAME_H #include #ifdef HAVE_LAME #include #endif /* HAVE_LAME */ #include "file_encoder.h" #ifdef HAVE_LAME #define LAME_READ 1024 #define LAME_BUFSIZE (LAME_READ + LAME_READ/4 + 7200) #define RB_LAME_SIZE (1<<18) typedef struct _lame_pencdata_t { FILE * out; rb_t * rb; lame_global_flags * gf; int channels; } lame_pencdata_t; #endif /* HAVE_LAME */ encoder_t * lame_encoder_init(file_encoder_t * fenc); #ifdef HAVE_LAME void lame_encoder_destroy(encoder_t * enc); int lame_encoder_open(encoder_t * enc, encoder_mode_t * mode); void lame_encoder_close(encoder_t * enc); unsigned int lame_encoder_write(encoder_t * enc, float * data, int num); int lame_encoder_validate_bitrate(int requested, int idx_offset); #endif /* HAVE_LAME */ #endif /* _ENC_LAME_H */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/encoder/enc_lame.c0000644000175000001440000001600010722255570015231 00000000000000/* -*- linux-c -*- Copyright (C) 2005 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: enc_lame.c 893 2007-11-25 11:24:39Z tszilagyi $ */ #include #include #include #include #include "../i18n.h" #include "../metadata.h" #include "../metadata_ape.h" #include "../metadata_id3v1.h" #include "../metadata_id3v2.h" #include "enc_lame.h" #ifdef HAVE_LAME extern options_t options; void lame_encoder_printf(const char * format, va_list ap) { (void)vfprintf(stdout, format, ap); } encoder_t * lame_encoder_init(file_encoder_t * fenc) { encoder_t * enc = NULL; if ((enc = calloc(1, sizeof(encoder_t))) == NULL) { fprintf(stderr, "enc_lame.c: lame_encoder_new() failed: calloc error\n"); return NULL; } enc->fenc = fenc; if ((enc->pdata = calloc(1, sizeof(lame_pencdata_t))) == NULL) { fprintf(stderr, "enc_lame.c: lame_encoder_new() failed: calloc error\n"); return NULL; } enc->init = lame_encoder_init; enc->destroy = lame_encoder_destroy; enc->open = lame_encoder_open; enc->close = lame_encoder_close; enc->write = lame_encoder_write; return enc; } void lame_encoder_destroy(encoder_t * enc) { free(enc->pdata); free(enc); } int lame_encoder_validate_bitrate(int requested, int idx_offset) { int n_rates = 14; int rates[] = { 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 }; int idx = 0; int i; for (i = 0; i < n_rates-1; i++) { if (requested <= (rates[i] + rates[i+1]) / 2) { break; } } idx = i + idx_offset; if (idx < 0) idx = 0; if (idx > n_rates - 1) idx = n_rates - 1; return rates[idx]; } int lame_encoder_open(encoder_t * enc, encoder_mode_t * mode) { lame_pencdata_t * pd = (lame_pencdata_t *)enc->pdata; int ret; pd->out = fopen(mode->filename, "wb+"); if (pd->out == NULL) { fprintf(stdout, "lame_decoder_open(): unable to open file for writing: %s\n", mode->filename); return -1; } pd->gf = lame_init(); if (pd->gf == NULL) return -1; pd->channels = mode->channels; pd->rb = rb_create(mode->channels * sizeof(float) * RB_LAME_SIZE); lame_set_num_channels(pd->gf, mode->channels); lame_set_in_samplerate(pd->gf, mode->sample_rate); lame_set_mode(pd->gf, (mode->channels == 2) ? JOINT_STEREO : MONO); lame_set_quality(pd->gf, 2); /* algorithm quality selection: 2=high 5=medium 7=low */ if (mode->vbr) { lame_set_VBR(pd->gf, vbr_abr); lame_set_VBR_mean_bitrate_kbps(pd->gf, lame_encoder_validate_bitrate(mode->bps/1000, 0)); lame_set_VBR_min_bitrate_kbps(pd->gf, lame_encoder_validate_bitrate(mode->bps/1000, -14)); lame_set_VBR_max_bitrate_kbps(pd->gf, lame_encoder_validate_bitrate(mode->bps/1000, 2)); } else { lame_set_brate(pd->gf, lame_encoder_validate_bitrate(mode->bps/1000, 0)); } lame_set_errorf(pd->gf, lame_encoder_printf); lame_set_debugf(pd->gf, lame_encoder_printf); lame_set_msgf(pd->gf, lame_encoder_printf); if (mode->write_meta && options.batch_mpeg_add_id3v2) { unsigned char * buf; int length; int padding_size; if (mode->meta != NULL) { metadata_to_id3v2(mode->meta, &buf, &length); padding_size = meta_id3v2_padding_size(length); meta_id3v2_pad(&buf, &length, padding_size); meta_id3v2_write_tag(pd->out, buf, length); } } ret = lame_init_params(pd->gf); return (ret >= 0) ? 0 : -1; } void lame_encode_block(lame_pencdata_t * pd) { int i; short int l[LAME_READ]; short int r[LAME_READ]; unsigned char mp3buf[LAME_BUFSIZE]; int n_encoded; int n_avail = rb_read_space(pd->rb) / pd->channels / sizeof(float); if (n_avail > LAME_READ) n_avail = LAME_READ; for (i = 0; i < n_avail; i++) { float f; rb_read(pd->rb, (char *)&f, sizeof(float)); l[i] = 32768.0 * f; if (pd->channels == 2) { rb_read(pd->rb, (char *)&f, sizeof(float)); r[i] = 32768.0 * f; } else { r[i] = l[i]; } } n_encoded = lame_encode_buffer(pd->gf, l, r, n_avail, mp3buf, LAME_BUFSIZE); if (n_encoded < 0) { printf("enc_lame.c: encoding error\n"); return; } if (fwrite(mp3buf, 1, n_encoded, pd->out) != n_encoded) { printf("enc_lame.c: file write error\n"); return; } } unsigned int lame_encoder_write(encoder_t * enc, float * data, int num) { lame_pencdata_t * pd = (lame_pencdata_t *)enc->pdata; rb_write(pd->rb, (char *)data, num * pd->channels * sizeof(float)); while (rb_read_space(pd->rb) > LAME_READ * pd->channels * sizeof(float)) { lame_encode_block(pd); } return num; } void lame_encoder_close(encoder_t * enc) { lame_pencdata_t * pd = (lame_pencdata_t *)enc->pdata; unsigned char mp3buf[LAME_BUFSIZE]; int n_encoded; lame_encode_block(pd); n_encoded = lame_encode_flush(pd->gf, mp3buf, LAME_BUFSIZE); if (n_encoded < 0) { printf("enc_lame.c: encoding error\n"); return; } if (fwrite(mp3buf, 1, n_encoded, pd->out) != n_encoded) { printf("enc_lame.c: file write error\n"); return; } fflush(pd->out); lame_mp3_tags_fid(pd->gf, pd->out); lame_close(pd->gf); fseek(pd->out, 0L, SEEK_END); if (enc->mode->write_meta && options.batch_mpeg_add_ape) { ape_tag_t tag; memset(&tag, 0x00, sizeof(ape_tag_t)); metadata_to_ape_tag(enc->mode->meta, &tag); if (tag.header.item_count > 0) { int length = tag.header.tag_size + 32; unsigned char * data = calloc(1, length); if (data == NULL) { fprintf(stderr, "enc_lame.c: calloc error\n"); return; } meta_ape_render(&tag, data); if (data != NULL && length > 0) { if (fwrite(data, 1, length, pd->out) != length) { fprintf(stderr, "enc_lame.c: fwrite() failed\n"); fclose(pd->out); return; } } free(data); } meta_ape_free(&tag); } if (enc->mode->write_meta && options.batch_mpeg_add_id3v1) { if (metadata_get_frame_by_tag(enc->mode->meta, META_TAG_ID3v1, NULL) != NULL) { int ret; unsigned char id3v1[128]; ret = metadata_to_id3v1(enc->mode->meta, id3v1); if (ret != META_ERROR_NONE) { fprintf(stderr, "enc_lame.c: metadata_to_id3v1() returned %d\n", ret); return; } if (fwrite(id3v1, 1, 128, pd->out) != 128) { fprintf(stderr, "enc_lame.c: fwrite() failed\n"); fclose(pd->out); return; } } } rb_free(pd->rb); fclose(pd->out); } #else encoder_t * lame_encoder_init(file_encoder_t * fenc) { return NULL; } #endif /* HAVE_LAME */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/encoder/enc_sndfile.h0000644000175000001440000000305310612341731015741 00000000000000/* -*- linux-c -*- Copyright (C) 2005 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: enc_sndfile.h 490 2006-12-17 18:24:59Z tszilagyi $ */ #ifndef _ENC_SNDFILE_H #define _ENC_SNDFILE_H #ifdef HAVE_SNDFILE #include #endif /* HAVE_SNDFILE */ #include "file_encoder.h" #ifdef HAVE_SNDFILE typedef struct _sndfile_pencdata_t { SF_INFO sf_info; SNDFILE * sf; } sndfile_pencdata_t; #endif /* HAVE_SNDFILE */ encoder_t * sndfile_encoder_init(file_encoder_t * fenc); #ifdef HAVE_SNDFILE void sndfile_encoder_destroy(encoder_t * enc); int sndfile_encoder_open(encoder_t * enc, encoder_mode_t * mode); void sndfile_encoder_close(encoder_t * enc); unsigned int sndfile_encoder_write(encoder_t * enc, float * data, int num); #endif /* HAVE_SNDFILE */ #endif /* _ENC_SNDFILE_H */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/encoder/enc_sndfile.c0000644000175000001440000000530610612341731015737 00000000000000/* -*- linux-c -*- Copyright (C) 2005 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: enc_sndfile.c 485 2006-12-13 21:02:05Z tszilagyi $ */ #include #include #include #include #include "../i18n.h" #include "enc_sndfile.h" #ifdef HAVE_SNDFILE encoder_t * sndfile_encoder_init(file_encoder_t * fenc) { encoder_t * enc = NULL; if ((enc = calloc(1, sizeof(encoder_t))) == NULL) { fprintf(stderr, "enc_sndfile.c: sndfile_encoder_new() failed: calloc error\n"); return NULL; } enc->fenc = fenc; if ((enc->pdata = calloc(1, sizeof(sndfile_pencdata_t))) == NULL) { fprintf(stderr, "enc_sndfile.c: sndfile_encoder_new() failed: calloc error\n"); return NULL; } enc->init = sndfile_encoder_init; enc->destroy = sndfile_encoder_destroy; enc->open = sndfile_encoder_open; enc->close = sndfile_encoder_close; enc->write = sndfile_encoder_write; return enc; } void sndfile_encoder_destroy(encoder_t * enc) { free(enc->pdata); free(enc); } int sndfile_encoder_open(encoder_t * enc, encoder_mode_t * mode) { sndfile_pencdata_t * pd = (sndfile_pencdata_t *)enc->pdata; pd->sf_info.samplerate = mode->sample_rate; pd->sf_info.channels = mode->channels; pd->sf_info.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16; if ((pd->sf = sf_open(mode->filename, SFM_WRITE, &(pd->sf_info))) == NULL) { return -1; } return 0; } void sndfile_encoder_close(encoder_t * enc) { sndfile_pencdata_t * pd = (sndfile_pencdata_t *)enc->pdata; sf_close(pd->sf); } unsigned int sndfile_encoder_write(encoder_t * enc, float * data, int num) { sndfile_pencdata_t * pd = (sndfile_pencdata_t *)enc->pdata; unsigned int numwritten = 0; numwritten = sf_writef_float(pd->sf, data, num); return numwritten; } #else encoder_t * sndfile_encoder_init(file_encoder_t * fenc) { return NULL; } #endif /* HAVE_SNDFILE */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/encoder/enc_vorbis.h0000644000175000001440000000345710612341731015631 00000000000000/* -*- linux-c -*- Copyright (C) 2005 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: enc_vorbis.h 490 2006-12-17 18:24:59Z tszilagyi $ */ #ifndef _ENC_VORBIS_H #define _ENC_VORBIS_H #include #ifdef HAVE_VORBISENC #include #endif /* HAVE_VORBISENC */ #include "file_encoder.h" #ifdef HAVE_VORBISENC #define VORBISENC_READ 1024 #define RB_VORBISENC_SIZE (1<<18) typedef struct _vorbisenc_pencdata_t { FILE * out; rb_t * rb; int eos; int channels; ogg_stream_state os; ogg_page og; ogg_packet op; vorbis_info vi; vorbis_comment vc; vorbis_dsp_state vd; vorbis_block vb; } vorbisenc_pencdata_t; #endif /* HAVE_VORBISENC */ encoder_t * vorbisenc_encoder_init(file_encoder_t * fenc); #ifdef HAVE_VORBISENC void vorbisenc_encoder_destroy(encoder_t * enc); int vorbisenc_encoder_open(encoder_t * enc, encoder_mode_t * mode); void vorbisenc_encoder_close(encoder_t * enc); unsigned int vorbisenc_encoder_write(encoder_t * enc, float * data, int num); #endif /* HAVE_VORBISENC */ #endif /* _ENC_VORBIS_H */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/encoder/enc_vorbis.c0000644000175000001440000001373210730024025015614 00000000000000/* -*- linux-c -*- Copyright (C) 2005 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: enc_vorbis.c 920 2007-12-12 18:01:46Z peterszilagyi $ */ #include #include #include #include #include #include #include "../i18n.h" #include "enc_vorbis.h" #ifdef HAVE_VORBISENC encoder_t * vorbisenc_encoder_init(file_encoder_t * fenc) { encoder_t * enc = NULL; if ((enc = calloc(1, sizeof(encoder_t))) == NULL) { fprintf(stderr, "enc_vorbisenc.c: vorbisenc_encoder_new() failed: calloc error\n"); return NULL; } enc->fenc = fenc; if ((enc->pdata = calloc(1, sizeof(vorbisenc_pencdata_t))) == NULL) { fprintf(stderr, "enc_vorbisenc.c: vorbisenc_encoder_new() failed: calloc error\n"); return NULL; } enc->init = vorbisenc_encoder_init; enc->destroy = vorbisenc_encoder_destroy; enc->open = vorbisenc_encoder_open; enc->close = vorbisenc_encoder_close; enc->write = vorbisenc_encoder_write; return enc; } void vorbisenc_encoder_destroy(encoder_t * enc) { free(enc->pdata); free(enc); } int vorbisenc_encoder_open(encoder_t * enc, encoder_mode_t * mode) { vorbisenc_pencdata_t * pd = (vorbisenc_pencdata_t *)enc->pdata; int ret; pd->out = fopen(mode->filename, "wb"); if (pd->out == NULL) { fprintf(stdout, "vorbisenc_encoder_open(): unable to open file for writing: %s\n", mode->filename); return -1; } vorbis_info_init(&pd->vi); ret = (vorbis_encode_setup_managed(&pd->vi, mode->channels, mode->sample_rate, -1, mode->bps, -1) || vorbis_encode_ctl(&pd->vi, OV_ECTL_RATEMANAGE2_SET, NULL) || vorbis_encode_setup_init(&pd->vi)); if (ret) return -1; vorbis_comment_init(&pd->vc); if (mode->write_meta) { meta_frame_t * frame; frame = metadata_get_frame_by_tag(mode->meta, META_TAG_OXC, NULL); while (frame != NULL) { char * str; char * field_val = NULL; char fval[MAXLEN]; char * renderfmt = meta_get_field_renderfmt(frame->type); meta_get_fieldname_embedded(META_TAG_OXC, frame->type, &str); if (META_FIELD_TEXT(frame->type)) { field_val = frame->field_val; } else if (META_FIELD_INT(frame->type)) { snprintf(fval, MAXLEN-1, renderfmt, frame->int_val); field_val = fval; } else if (META_FIELD_FLOAT(frame->type)) { snprintf(fval, MAXLEN-1, renderfmt, frame->float_val); field_val = fval; } vorbis_comment_add_tag(&pd->vc, str, field_val); frame = metadata_get_frame_by_tag(mode->meta, META_TAG_OXC, frame); } } vorbis_analysis_init(&pd->vd, &pd->vi); vorbis_block_init(&pd->vd, &pd->vb); srand(time(NULL)); ogg_stream_init(&pd->os, rand()); { ogg_packet header; ogg_packet header_comm; ogg_packet header_code; vorbis_analysis_headerout(&pd->vd, &pd->vc, &header, &header_comm, &header_code); ogg_stream_packetin(&pd->os, &header); ogg_stream_packetin(&pd->os, &header_comm); ogg_stream_packetin(&pd->os, &header_code); while (1) { int result = ogg_stream_flush(&pd->os, &pd->og); if (result == 0) break; fwrite(pd->og.header, 1, pd->og.header_len, pd->out); fwrite(pd->og.body, 1, pd->og.body_len, pd->out); } } pd->rb = rb_create(mode->channels * sizeof(float) * RB_VORBISENC_SIZE); pd->channels = mode->channels; pd->eos = 0; return 0; } void vorbisenc_read_and_analyse(vorbisenc_pencdata_t * pd, int n_frames) { int i, j; float ** buffer = vorbis_analysis_buffer(&pd->vd, n_frames); for (i = 0; i < n_frames; i++) { for (j = 0; j < pd->channels; j++) { rb_read(pd->rb, (char *)(&(buffer[j][i])), sizeof(float)); } } vorbis_analysis_wrote(&pd->vd, n_frames); } void vorbisenc_encode_blocks(vorbisenc_pencdata_t * pd) { while (vorbis_analysis_blockout(&pd->vd, &pd->vb) == 1) { vorbis_analysis(&pd->vb, NULL); vorbis_bitrate_addblock(&pd->vb); while (vorbis_bitrate_flushpacket(&pd->vd, &pd->op)) { ogg_stream_packetin(&pd->os, &pd->op); while (!pd->eos) { int result = ogg_stream_pageout(&pd->os, &pd->og); if (result == 0) break; fwrite(pd->og.header, 1, pd->og.header_len, pd->out); fwrite(pd->og.body, 1, pd->og.body_len, pd->out); if (ogg_page_eos(&pd->og)) pd->eos = 1; } } } } unsigned int vorbisenc_encoder_write(encoder_t * enc, float * data, int num) { vorbisenc_pencdata_t * pd = (vorbisenc_pencdata_t *)enc->pdata; rb_write(pd->rb, (char *)data, num * pd->channels * sizeof(float)); while (rb_read_space(pd->rb) > VORBISENC_READ * pd->channels * sizeof(float)) { vorbisenc_read_and_analyse(pd, VORBISENC_READ); vorbisenc_encode_blocks(pd); } return num; } void vorbisenc_encoder_close(encoder_t * enc) { vorbisenc_pencdata_t * pd = (vorbisenc_pencdata_t *)enc->pdata; int space = rb_read_space(pd->rb) / pd->channels / sizeof(float); vorbisenc_read_and_analyse(pd, space); vorbisenc_encode_blocks(pd); vorbis_analysis_wrote(&pd->vd, 0); vorbisenc_encode_blocks(pd); ogg_stream_clear(&pd->os); vorbis_block_clear(&pd->vb); vorbis_dsp_clear(&pd->vd); vorbis_comment_clear(&pd->vc); vorbis_info_clear(&pd->vi); rb_free(pd->rb); fclose(pd->out); } #else encoder_t * vorbisenc_encoder_init(file_encoder_t * fenc) { return NULL; } #endif /* HAVE_VORBISENC */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/encoder/file_encoder.h0000644000175000001440000000500611002132477016105 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: file_encoder.h 1019 2008-04-13 15:16:27Z peterszilagyi $ */ #ifndef _FILE_ENCODER_H #define _FILE_ENCODER_H #include "../common.h" #include "../metadata.h" #include "../rb.h" #ifdef __cplusplus extern "C" { #endif /* output libs */ #define ENC_SNDFILE_LIB 0 #define ENC_FLAC_LIB 1 #define ENC_VORBIS_LIB 2 #define ENC_LAME_LIB 3 #define ENC_COPY 4 /* does not count in N_ENCODERS */ #define N_ENCODERS 4 typedef struct _encoder_mode_t { int file_lib; char filename[MAXLEN]; unsigned long sample_rate; int channels; int bps; /* meaningful only with Vorbis and LAME */ int vbr; /* meaningful only with LAME */ int clevel; /* 0(fastest)-8(best), meaningful only with FLAC */ int write_meta; metadata_t * meta; } encoder_mode_t; typedef struct _file_encoder_t { int file_open; void * penc; /* actually, it's (encoder_t *) */ } file_encoder_t; typedef struct _encoder_t { file_encoder_t * fenc; encoder_mode_t * mode; void * pdata; /* opaque pointer to encoder-dependent struct */ struct _encoder_t * (* init)(file_encoder_t * fenc); void (* destroy)(struct _encoder_t * enc); int (* open)(struct _encoder_t * enc, encoder_mode_t * mode); void (* close)(struct _encoder_t * enc); unsigned int (* write)(struct _encoder_t * enc, float * data, int num); } encoder_t; file_encoder_t * file_encoder_new(void); void file_encoder_delete(file_encoder_t * fenc); int file_encoder_open(file_encoder_t * fenc, encoder_mode_t * mode); void file_encoder_close(file_encoder_t * fenc); unsigned int file_encoder_write(file_encoder_t * fenc, float * data, int num); #ifdef __cplusplus } /* extern "C" */ #endif #endif /* _FILE_ENCODER_H */ // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/encoder/file_encoder.c0000644000175000001440000000557610722255570016124 00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: file_encoder.c 893 2007-11-25 11:24:39Z tszilagyi $ */ #include #include #include #include #include "file_encoder.h" #include "enc_flac.h" #include "enc_lame.h" #include "enc_vorbis.h" #include "enc_sndfile.h" extern size_t sample_size; typedef encoder_t * encoder_init_t(file_encoder_t * fenc); /* positions in this array have to agree with the ENC_*_LIB values in file_encoder.h */ encoder_init_t * encoder_init_v[N_ENCODERS] = { sndfile_encoder_init, flac_encoder_init, vorbisenc_encoder_init, lame_encoder_init }; file_encoder_t * file_encoder_new(void) { file_encoder_t * fenc = NULL; if ((fenc = calloc(1, sizeof(file_encoder_t))) == NULL) { fprintf(stderr, "file_encoder.c: file_encoder_new() failed: calloc error\n"); return NULL; } fenc->file_open = 0; fenc->penc = NULL; return fenc; } void file_encoder_delete(file_encoder_t * fenc) { if (fenc->file_open) { file_encoder_close(fenc); } free(fenc); } /* return: 0 is OK, >0 is error */ int file_encoder_open(file_encoder_t * fenc, encoder_mode_t * mode) { encoder_t * enc; if (mode->filename == NULL) { fprintf(stderr, "Warning: filename == NULL passed to file_encoder_open()\n"); return 1; } enc = encoder_init_v[mode->file_lib](fenc); if (!enc) { fprintf(stderr, "Warning: error initializing encoder %d.\n", mode->file_lib); return 1; } if (enc->open(enc, mode) != 0) { fprintf(stderr, "Warning: error opening encoder %d.\n", mode->file_lib); return 1; } enc->mode = mode; fenc->penc = (void *)enc; fenc->file_open = 1; return 0; } void file_encoder_close(file_encoder_t * fenc) { encoder_t * enc; if (!fenc->file_open) { return; } enc = (encoder_t *)(fenc->penc); enc->close(enc); enc->destroy(enc); fenc->penc = NULL; fenc->file_open = 0; } /* data should point to (num * channels) number of float values */ unsigned int file_encoder_write(file_encoder_t * fenc, float * data, int num) { encoder_t * enc = (encoder_t *)(fenc->penc); return enc->write(enc, data, num); } // vim: shiftwidth=8:tabstop=8:softtabstop=8 : aqualung-0.9beta11/src/img/0000777000175000001440000000000011331334363012541 500000000000000aqualung-0.9beta11/src/img/Makefile.am0000644000175000001440000000010710715346600014511 00000000000000imagedir = $(pkgdatadir) image_DATA = *.png EXTRA_DIST = $(image_DATA) aqualung-0.9beta11/src/img/Makefile.in0000644000175000001440000002247111331334253014526 00000000000000# Makefile.in generated by automake 1.10.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # This Makefile.in 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. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = src/img DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = SOURCES = DIST_SOURCES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; am__installdirs = "$(DESTDIR)$(imagedir)" imageDATA_INSTALL = $(INSTALL_DATA) DATA = $(image_DATA) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBAVCODEC_CFLAGS = @LIBAVCODEC_CFLAGS@ LIBAVCODEC_LIBS = @LIBAVCODEC_LIBS@ LIBAVFORMAT_CFLAGS = @LIBAVFORMAT_CFLAGS@ LIBAVFORMAT_LIBS = @LIBAVFORMAT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ var = @var@ imagedir = $(pkgdatadir) image_DATA = *.png EXTRA_DIST = $(image_DATA) all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/img/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/img/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh install-imageDATA: $(image_DATA) @$(NORMAL_INSTALL) test -z "$(imagedir)" || $(MKDIR_P) "$(DESTDIR)$(imagedir)" @list='$(image_DATA)'; for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ f=$(am__strip_dir) \ echo " $(imageDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(imagedir)/$$f'"; \ $(imageDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(imagedir)/$$f"; \ done uninstall-imageDATA: @$(NORMAL_UNINSTALL) @list='$(image_DATA)'; for p in $$list; do \ f=$(am__strip_dir) \ echo " rm -f '$(DESTDIR)$(imagedir)/$$f'"; \ rm -f "$(DESTDIR)$(imagedir)/$$f"; \ done tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(DATA) installdirs: for dir in "$(DESTDIR)$(imagedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-imageDATA install-dvi: install-dvi-am install-exec-am: install-html: install-html-am install-info: install-info-am install-man: install-pdf: install-pdf-am install-ps: install-ps-am installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-imageDATA .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic distclean \ distclean-generic distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-imageDATA install-info install-info-am \ install-man install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic pdf pdf-am ps ps-am uninstall \ uninstall-am uninstall-imageDATA # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: aqualung-0.9beta11/src/img/appearance.png0000644000175000001440000000366010612341731015265 00000000000000PNG  IHDR szz pHYs  tIME6otEXtCommentCreated with The GIMPd%n&IDATXõߏ]U?ksa3j-hb?PBj mH@1c|/#FhU@!A?*J'νss={ù3[;~9Z>G>ۣn"7+ξ$7;Qp*!*! Nq9uDPἵKcޛgOZB~]w.~ᙅv"A!!q|prqRN|^;vx/1,1FAȱcG+` b͈"((HG\4k(N qhhh᦭7Yj  J?7677WA03CDi8ι1=O0 A Q9yv?D5ojz^Fk f`E4 !Gxݛ7"~w sۗZ7Al3dmTiDՀ>Ġ)#ב\Ol!fdYU3z=4*fVlp@IQU,;ϹjJTŢaV0#!,It:j`4Md]ܨQor9j1TUe5")%RWTqINøu8sijB\ ; 1:Ζ`Ƃ$D7pߜ8u!FDvi1€+ƽ)N("4#F]7"S#osۖM<¶@ȲlQvRPe}c4I h{zpgо`.LBXE5 ĪJ`9b5 i ! H{ ~$F39b]\ !j6yr_ä@q@ WK v)vdj/'%L(PѠ/-i L4QoԱQ%<"Xi47T*hiO;(J/x-6sr 0Ұb!TUk "~'їdAɂYYU/Pm6fg:^ {y{p{ꐦ)w.JyrvӦ-LM]Iw034Es<}s3#I8W,f^zJmlwaxx3cbbe||juW]KG/5[7v v{kpjLOs ~r-lqj#G{Y}#K7;q:wÇg $r9ɋCjg,$8Aal>lOKO$'Cy/x8o쩵b=a&IENDB`aqualung-0.9beta11/src/img/cdda.png0000644000175000001440000000470510612341731014062 00000000000000PNG  IHDR szzsBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org< BIDATXW l=3;l !AiKqcPDڈ&M JԴU6jhTAU%i("C66?313;֦64̛w=(d7YsqiotީBBN5Y8Σٹǫj$˧(h,Sk_X io単#ʔ`0;c!Nsj*<¥+8ܜj J*DH2 s!ֺ@ D(?mcSf2x6>V;|~M/ UD)ȁ#\S8ptًWVa|xT>j_WžAG>~pW+>6unƓ nBPVXYJ޲ [<ȍ؁Y3gvfwʕf2γ[BB0lOGzp…Pգ@?>u~cͷJoݺU.X_ (b7Y_cOΝKD$CBҀDŽeHIIA&"[[L8 ^ɓ \ t][9?zS8Y'j&ut~*@8uUUU!P`Ehhh@ڬYPhKJJ_>N ( JA"FCP8QWpn8}40 jkkqcҋe&zO9i3EK2!lMZ`9F{G%|4%!s1x\|EEE79z+eqqȲR ZBu!]DaK& (:wrKKJ/FE=̙CР3L4I;|F 5y`<Vَ$,LWBѐ2\nm}gH$#h^{y5ΞKG {OPiy%TգɬFʩ@ACn@T;hh<46|Jʑ%%N:Hiȴ)TD: 7*pkܐwvwC ,!CUZ%>*1cp8[Y,%.h @!/3g[͡Ў3? XV.,ADtbͧl]ӖFDq Q1*I%z{%Kh+7ɏpdn PA ,n⫒^ g^}Λ]Y׷38,'YJ17}lJ NHfXG&+`2SrTĠ>Ao- B1޵k>++7'X}Æa0´o!a }(1Y(R oMbFȏX*ǘ\oۖ|脊rm8LAV` c'ȵCZ7|ހf" )dXx~_oV@)K_Z3Ƥ"\a+FqM. }@^rE('ւCDw=B Z OЋ]MK=]l3--b[/ڼ# (X.ESJWpNfKd] RЬc-':ȯ?W[Գ+#/.]1?V6r}@@-k+Hy6{눛InܵcDr&wы 3\TV:őmqq%AY,VC-'[n]Af-e9}ܯ??殑jPhyP_2Nli1:c!~7x_4ݫ hfwfjaET*';_o]#Ԇn2IENDB`aqualung-0.9beta11/src/img/cddb.png0000644000175000001440000000400610612341731014055 00000000000000PNG  IHDR szz pHYs  tIME,ZtEXtCommentCreated with The GIMPd%n|IDATXW[P:Lۋ.NWih I.2iL4vըEP qj$M2Kccp1aa9]XOrAa`)jb&;̿?~߿i7;%;N̸F̫kjodbIC=]M?~2IaɊl?0`nCN#-SLk/xx_M#bPN }CCppavnko}kC|[\\JmCBF#[ZL&4lFbƧ0ʪ7wH; &yѓpb D*bMȡ4|Uܹv_~}E<̳~O'%g&__ rn=v;Ѡ)$'%YEgg'xql7ӎX`| >q+ӛQ]׀zW"0ǽ_ZZ=10FGH}fAEU!ߵ$-,Gvn*򊐴}U yEE9άC*YLز9agDp2ۋBa<ˎd*D$QXٳe* "x]ZMZڬ*L&1f\*Ʉ^ NN $ HG@ɻ< ؒχF^ku0}`p@;62$cqR]~LݍAz3w(Z=<FLos ۶W $Ѵm:l-,-faK[ǍlB K0tqx|~UWH~·o{ɸ̂ WM͘6&Z6lںF;X71HIIGu)`Adee "߯g(shooW"(ࣂ~E$!NvZPN(cڎ!ԀfYtI`%![>vxh{Pp(h͕Zi_M[gL}ф we񥝽c~laV,.W7" hjPqbbr5?tRZQ;+"Q5H&ExOoC&bU^/ڇA_ f`Vfun~^Yw7F?ϝ_BCeThnB,DGde/17YsV|<^Ctd^% ,E*BFFFCXF%R T,"N[򊪔jH nG$C46CT:E :jP@_Ald4Q?mCG@:tl4[[Džѵf`o7kUZlvy!ֈL’ܲ/:>q͸ذ,LHdlE IH6.*]"*_\PM#iL`v|245j8~[Z:DWhAqRnB B(lbiV\ n޻Ϋ@g7 RA$VA'QG.|k}px^OMNWr0aQYtv aRP; ayڛ7~pz6[)B),B *WOlK/0r/tFRJXfO)EnC2$G%nxdϱekakW8;DDDDzRJq3VT#{?IOhcKDӫ,!|ol hf49c,tβ?,Mj5R:_Z;63ήy=Jͤ5 ӺeYgvHLpܴ;d&e<گ-"7UmMeBT9 =ppwyjlX!$iE 0tSR=GT`op?  uc%x9nqZÖF ]5yxߟܩ6mw{/ wXNHY7tM"υR~Yg1Yw:t\[{䙟־qWJVv=()*9~ğI WHEot4zJ%tt!ZZ5ͰL2)f 45aWOd%g{P{h)`E%B>O`fj Ae:Nmщ:.f\KmlecE{ GI 0H(5mK~/utڄVv^*@@qL[hcl m[r@RnC @fZꇨV}Da$at L1J]oMb44&T#ӳ>9]\ r JC!Ll&1ٯ~YTп)Q \ \Q ЉkRۅ~xUNŸ̞:9* iCk$NQ*bWa%ѳ2 .QX߶RIXc G엑eX0g ~y_lkxjXG[SgY BJ Ag!ta3p'hpdhQO!|ikCG%a_d>1b4_b6v݆g;lh녧vk+> @?# =1NMax`@;7=LG"J nDoOØL`XZ2ϝ >ׯ^uܸ[7o۸.|{?|Ǐ?W7lVt3(E(Wh"%6֎vfKD(g(F `d8 Rk< HuSVِ QUtbm48EѿSFhѯoRRX(@p{H#4Ad!H&T -B!K44A:{E>+I5 idN 74壑`/n~q+thm%ݪd"DRpb >uG4 LOC֩J&cm}zC Ħcd DSuڵ ix+q/E$N0rV1Bh*NSqJJʮX>##cuPߵ> "z_W*mѓM5ƛ,"c@DE~`&k퇯]_ilGUr3w8g־8 HD^vA"ZZض=h:9K.2h3bտn @D.>Z i?\۽\s˰.r_ؐړ(/EW;"8qoc{b <љQJܾA_Yk"2(YNk4rb ג±zEA/p M<ЛK elL |j>OCM}ϿRaUwG8ڡT_w\]z7XkS"7SdԂ玬R]>~⺚uB;$Ў:TZ:_"%k${q/-|kâ(p:bɐv^7Y#+"R:ࡳ?'|}D:׊sI%ju'pݼos. 1\,\[oҲCiDqt/YN{˪+|M{tTDC ذy֯/,Y2xϞ7(E_O7fV_]z)A259=&qy===$?\<]vK}ڸ6n-[,(ܷWzϞ=[ze96q;N7 ox׼:rkZ#J|p%-OLxa^7-]ưzhk}=/|R;vfAvf5#hۭSSSiZuL7ųMѽtvjȴr5xWˮ'+<ymvf0igby16K9=_1ֵ 9JxQ0۳}Hq 94&ga+ޅxP^d0&O7;OYS44nF:i=711@Y`ݟÇIp*Od,e?װRTܾK::cm14 0?<~N'M<53s[P:Ir@i Mw2ܒK;9S$᣸&㒢ܸf <0Ǵ7D ei7tLNLO5ݪj=0WC65fu0a'V吤9Hr撌8c&NSک!P9fR9;RkG5f 4ϳyokF= j~,UZ虇<^=l6ۙa!əigl%lw%kX\O~}5=-kA{zZڳ%gttTe}TD4`w- ,&]K9pҊ~"0 0;3-JUHN/rMbcIENDB`aqualung-0.9beta11/src/img/icon_16.png0000644000175000001440000000153410615100503014413 00000000000000PNG  IHDRasBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<IDAT8[H.}>55H o]((_VZot^A7P%z(衂 *{ʠ\Bm~KA 8OÏsjus sL9WmX],IR'1S^TH?&QdH%2M-TRmt߳˒tw:DGà'cYjc c{Z3F#q|L&GID!XNpnD=`6'1([r ߾q(RĄ=Ntx%H:kQ{{}Q$I^jSԛާ}cq+6ͩ*K<>m@<`86e<t=" k֭i#fSaXӴC!H,{rjzpߧ|!={'B#;p/rIENDB`aqualung-0.9beta11/src/img/icon_24.png0000644000175000001440000000300410615100503014404 00000000000000PNG  IHDRw= pHYs B(xtIME&d]IDATHǭ}lU?y~{{[ڮoZa jő$qٖD!2C8Tױ!Ƙl$5AJKGV޶[{}}rg$>}|PJO3%0]!R%u/f qgFv !Ł"y qϱ@S,~:(!9آz0=q_~F5bZ۔\e!BjKb6}3 F}ȷ? vf2dl]ф1 ,"J U:yog7j( !;:*w9Z=   CԉBDH1}n@brëm8r&r) ԕ"N@ @XQ*VWiV5tuu7Mߗ, yߎ[%]R~s02sy!TqPhB!I4A-U-+w.I4qرlLm߾ׇ^7.^Z8=9o/WPQWYFĉ4$QrHW}8Jo~-޽KRMSdb|LkX9x^a2S,]ALSc44I\i{u;iq [Zz0$UJ1Q$!b$ D3}k>AXgEt]vJ xod$<Pu6& .$bv4F~5t)^̂dl@s3ɵKzqf&yގ.GqPs2~[FcZ6aHҶA*^b7<3:fg'lEqP_z[ּE]A4އ@ 7XuǹF}xT*/sWJسw{FΎlW~w8QMIkO: B$(]I֒bͯ=ڙ@o:mmƛ(p4ٳvмǼt6O]3҆ףRRZ(^_8ZWZ|Oh&ntfi_rmmL[$!3lL0>T\ѡբAwpc uJI|.@I?1dqIENDB`aqualung-0.9beta11/src/img/icon_32.png0000644000175000001440000000454610615100503014417 00000000000000PNG  IHDR szz pHYs B(xtIME&P IDATXí}l\W陱=c':6M҆6IЦ6@a–,!a:, (T,مEلFT tQAU?ZҒi|8=cܙ{{J {ϕ^`B6[w-n._n+? q_k  UEZ -{E@gV>Pߵ> "z_W*mѓM5ƛ,"c@DE~`&k퇯]_ilGUr3w8g־8 HD^vA"ZZض=h:9K.2h3bտn @D.>Z i?\۽\s˰.r_ؐړ(/EW;"8qoc{b <љQJܾA_Yk"2(YNk4rb ג±zEA/p M<ЛK elL |j>OCM}ϿRaUwG8ڡT_w\]z7XkS"7SdԂ玬R]>~⺚uB;$Ў:TZ:_"%k${q/-|kâ(p:bɐv^7Y#+"R:ࡳ?'|}D:׊sI%ju'pݼos. 1\,\[oҲCiDqt/YN{˪+|M{tTDC ذy֯/,Y2xϞ7(E_O7fV_]z)A259=&qy===$?\<]vK}ڸ6n-[,(ܷWzϞ=[ze96q;N7 ox׼:rkZ#J|p%-OLxa^7-]ưzhk}=/|R;vfAvf5#hۭSSSiZuL7ųMѽtvjȴr5xWˮ'+<ymvf0igby16K9=_1ֵ 9JxQ0۳}Hq 94&ga+ޅxP^d0&O7;OYS44nF:i=711@Y`ݟÇIp*Od,e?װRTܾK::cm14 0?<~N'M<53s[P:Ir@i Mw2ܒK;9S$᣸&㒢ܸf <0Ǵ7D ei7tLNLO5ݪj=0WC65fu0a'V吤9Hr撌8c&NSک!P9fR9;RkG5f 4ϳyokF= j~,UZ虇<^=l6ۙa!əigl%lw%kX\O~}5=-kA{zZڳ%gttTe}TD4`w- ,&]K9pҊ~"0 0;3-JUHN/rMbcIENDB`aqualung-0.9beta11/src/img/icon_48.png0000644000175000001440000001042110615100503014413 00000000000000PNG  IHDR00WsBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<IDATh՚yU?K;Ȣ 0* 58 ֌06&θV:֨S LY *FG0BI-㽎?VWww9^ʇnC\ROKc/ѽ4^tM kc|GD6TA^dMMg0? ̕K|R-"b:fL^);Ű3 " )/5PhUX6‹>~^kʁ]"/"7/ O!kwƆMvuo,^~,ɾκPʖ9'"뀷!j=qg@Do8yccK_cE$, Py3>v\rp㜻X;3/ 89wsmڀNaSZt.hU*moo+{Ól: 7SDd ";uY@.5o^߾(* mN+/7…Yg vvssnxN"-:f F]#' ޷+F/yx&4 BҊ I  WUs!L^Z<(U]r~ȣZYQV3OgA{V$dqʪ(<#|lge\ \'"m ifaUNZ- >1||3YY0ɝ#NstXe1lc~ \ C>gpJY-Xft Hӵ)0Ja<JtSiVЈs8(w])S ZetpGfK٪JzM9]agɋXAJpi Ѻ*Q( J XJ G4\?,RT9#f"-j#ݝa)D,uOk!Y᰸߭!i<0ŠIHsA(LtYOz6zҎLD.V,ֵUS=o}N)7 hR x SIA[a9E5(V g9- M'sOŋXhYD?mN^ PM-;F3" G$/( gZ@-TSN)Iӌ8YZ.Cqs.lNo;QhtOhk< -\&b#*gպ3%Lc8Ց=GNZ"ӄ4 ,%R'auU>vߎ ;TO?dʶW.<|eтyA{{+q2[k0X]t[R.Tk֮ʣ;vb }G?봷EQ+T*$4p:&!K ?[Gf>EC h]ak_Mm߃L / 굺ڵ8^z?:VuTzz P4?VuB4o] +9ϊ^1>64l&es9|ϲmcɤť9^QG켏o(YENQya7>6*pB>Ji-iS^ȫs;?wpEӠ= ]I g ̥;o$>er ;zX}ע!)'JȒg-iPȓ)eM<Vn;<̜bjR ZbaNX _ pBpzn4"Z7HjSr>_X_fúyX 'bN&dEq @"I n4HӔ#G;@$9]VI,^c}ιZ͋f !w=P<9@eij<Ŵ%g(٬pidnj䶢T?>^2{?(Egtᔤi^,N\\DZqm$kĻk]$Gwu=:6dyx>:ʄe 9ڔz%j7QOu͍y^D8 ")gD:b$s$Ll;@h2@0l~'_M[wvy^{mhP( k3Ɋ%pI2V^ˤzkW2'EhAG eD8/B JmNetbs p~'|9b6kD1bؐ^b}GcXˁ@OXz*"`3p/s6c=_kFIӫfg4 x`|+6U=z|Jb8yS+٠7Ͽ4"ŚG#ļ9Uz\ |M~yéX7D\;w;UQݣ 74eZӫBh1l(#l^ $ 9홮 "|X``nٽ3mvgDLm1F4D6$bxCwy)W~uj[U x WD&6<-D$A/R=U38vuVӚs3Dk*hMyZO$ꗁ>;i "M vU-D1!0kǍK75XƢD V07esS\W~QDny:<4("Vzϣ1'zع6z:JDfuBb|EYyXK;ÿpޒȡ D*6=U xՉ ȲG{;U*Qib#I$$51cƈ̇\-:("RD ;TSxE-:2HX(Nlb!qt0aA%'MIj|n}S/78}']'%*wHN u!T#y+Z2]s6ol#rnaq\g-Ē8XI%νG9ceO۩Q'\0pI_!WKH5%qf0-ZLBP20)f7k&+Wxp{)"g<#Dd~W;C6&u2/:h5mֱ&, 1Xg0U!M6ƅUkp^M<w]A 1ׁJ>VfY,o|5fێa\Z5cH!B8!U>edsY\}Tw ԀΜ rFxI(9>lfU CR'!R%9 .HIw.; U}Ҙ졅}s?ld2%dIE}kcgV-,%"KO?/Yԡv EM7?XPx@=e^ Q⣢$6#KՌC_~p؎132260pd5KpcƀH\ bxG2PIfM /GueIcʧ+O;ދ=`IҘOݽySvX5z8c9`F FĚ2(C,<.F6$.Xp5O %&͓@DΣ?s[~F`15냇oκ1}\mQxϘOzi8wSѦa橔ȲA rE+F*b 8j,PE۱[(ΰOB! <€{͍9|<2pM5&TV@#!*h$hT`1bQzyI2ް[l*S`vg]e,qEZ>wk7Ihf Y%txUJ10>2eA611UDkLOIzY¶FjwJ;jz^jeg^+33|jHDD޾v/a9M<|<묳?<c$ƈӒ}G~>њ9@$2D!c*n }uk$xQU,/3iQ[I4MUWO97\ߺ#s獍}j];(Pv%rk_[=ѝ;wх.IEY(g~_066Ʈ]8Wk.mƖ-[شiiZ;@W]u5/~_MI?|=pS`߾}.z1wF>`jy{,]tG`eu##l?ί}ZUUܯs$M9cvʲyѹ912`hb H-o-GZydh-^`Yz%?:F8.9.Y*xdbΡ>Zsh.{,yUUeCZZgff2::Fpؘ8#՗~,dw!MYhhbDY2T,x?ǎ_]!_ &6KPţ/\3|IbD=_{.|8`ZN2JYT,t]ʲT,nlK4,c|@C R֝FVmwwRt_Ewq2t.;_.FןQGZѼs^;>TIctZ})^yq֙tR$ !hOWjQn1~ԑY:k6 KOZkWz{ GpƋ^/86MWAe+1Lo"-=>*uor0ga׶I2rd$H~L#IXDN]kزff(QY1FzJ@xYho[@U΋o/<;mʢOLR@"!C>T==QɃ t}]*#e4 f2%f,crF^FY9ԣ-R;!CYl>D#GfJߩ\(4z/\==t)ʂnC ?v}DːqU[81(V/(FHu+F(UӈzrxX78c07_3;ý{~y_jߣWT.Qp^ ";7rGF͡:#G\j:*U-QZbeW*e A F crQgէWK ́ 9Y}CyQCU</u$M_GP8~ԑ/rfLpr2Ɍ [P(`cW TqTEpaa$5R =|Py_xfrσ\#wO=缦}ODu $[6>\{{V˾p?)%Kfg˅$Bյ^EH^|E4 Ye,&Sa.CE-_*93KHT¾b9E 𭻾y -ɇƧcA2䜗f{a)SFȃHR"*;p֐Ȍ0d Y LuI","bi§~{|:?&11!#ockߑmo PDHI%xB;gT 5N$!#G2^+n'L}W2al`a*!MCnݎMᒫn0ctVgL%԰x q8T _Viqin3g}g/|~Oa}{}Py l6vlhԹXtv=/Zcm":vHD`5"NeKC,{Ym|Owgy~Ȕ}`v)tt:ܒӣP=ّh n6Ik(I}T6f%#kÓk]64 V0bjngIv3cwi Xf)eݞMkpHx=U, T7jШS kC4IZZh3YgRDU2/CP,-J/C|3gq bXC]PYij5c5DQQ_Ƀ=);2.ݼ }zeTU8 3diƄF%jRU& eP`-`q+rࡩnH* |cPCՊ4IEDDT"=5vr4'O00踿8|T>Kx;mv'}'9>CH: jIENDB`aqualung-0.9beta11/src/img/inet.png0000644000175000001440000000417110626626277014143 00000000000000PNG  IHDR szz pHYs B(xtIME$% wIDATXŗYP[3өNN>e}k^2clB !a ՀAb" 2"0u`;i7ÿ\4i=|{ ߾T7Q,f >::W<%F 'G!!aѡi0ɗ{q6Ss^xa '_|Junտ)F<W#m=m6*hZap\Caej ~ D 0e ^* Uʳq^)o]S繃k3 ט{?ڎ~+ oCc ʦNpKd …σ3 2RR9ircbxI`a]}܏2zW1@MTdzN pV81keBV Dpp2#1^"#_D _ 8> zm -~tN0F:ɨ[/{HQMDd4M&STf`N7Mu|eI%#"J[]e1PنGL0AZx$\ԃ]҂p^>]tbnXdFmr8I]םpBI{/ *uy$cPk09r+Ҥ&W;j)!gGΊ)FE5-H"[!1"UiE\nݞ /ݥe$ :I&RJ_GA( -D,N꿵c3Joת5 onP^LJ ԹHV\G$GIY%)HN0J'S'[<ĊHo@2/ޣ>Z5:Ff ~hbRy9NSi)%fZ(C\zY\ڣ|Z)|'sdv×y!$ڑVڎ3j&tE*L&|HaB  )V(Pxi} 7r(PC!H*fqtdy qgd H$iȖ!(,H ;@3i46o(QxG1>ߋ9b2I:DƓ!\P t}SP \Z x) %ېLmWlG$W)r8qp8tď])SQ'#!(aݗlfs%%xE6F=K >POv4 b뎇f$A_AhJ~D=lTOuD783˜\IENDB`aqualung-0.9beta11/src/img/logo.png0000644000175000001440000026356510612341731014142 00000000000000PNG  IHDRٿaA pHYs  tIME !+mbKGDgIDAT$1e? K1}0e F30b1{6fcf?1`ޔQYY`0bĈĘ#F cyc6͛=l6f77c~77o޼yϛy{޼{6oƛ0 l3"QTh$Z9s\geZde +Vd4j(eÀ0q̄Eʵ˗Z\.QjG)ע\6(8}fK;٬c4o5g?-L7TTt)8B^K,˕k%".۲Uc:]uƫW*no*Wo[mqm˶8>el% cTF8~۪0{˜ߔߺ?b0˦1 1b< 60&6o1҈G6(K,A  1b 6(Ad#x,16l61@ h`)MHE36`"bj,lo0ӍjYH+fm/tdfPe٦)hN`!bZ oU /W1"oĄySw[62(hٳ=PmKHU .kOCŌOPU1b`{;1x`D{>01gn00=zPmJ Axt#&lǞMg?=#FĈ#FA,10 b`1x326A @lfic,@"@ 6`Qڌe02X5)6f9ǻb_JoU1opRJ3K#1b ̦ TiS7Wmϝ նYബ/g=r܌Q"u݃TGz'JȆH[Hf\ @AgK}glbDP¸jU`[61ǫئԷ5m` DgN3^@b6h$6giƣM iH8{و2bS06 i0#L0'ƈM %x#8K l،lgg1c \lld qfDi{Ҫ6z< G|]R:[6;,vIY{ I cmN66cYJP8)e/ۦ,f6f3b6={<]P6#ukÐlktmlwGۘN1BW PQ{:~Nfl:bjmPi  ^c@6hw6̲c @)RJ:9(F $54Kl2)FblM a `60l1M ـDxӌ,("" `#Nfbb)f'26>=lHH@S#0Ch H3c3fl6cl6 0y1&мcl"4)E@lƛ 3,"H@0q 9ΆWt7αLղۢE)4)QfՌ jmŶl3Z\jVcBjvALʪ 6GiszMSC;QQ eBaamնyEyKEM'yoJޮ)˰˰gt!f* dgyM{9=%0J3L)S{K4 dQ 31c`) GLjHN;{7P6ț@`01 F3P1F# \ F͈`͛11ʦlb 4,P4ܢk[EK-g8iԕ4uff$G@P#1JAl1nbN5GVsDdq %@,)a#LJ7l$ll T%llh=xӦ{mۮٯN؆^} ?؞Xi6cb O1)CBLqx$0X1@0l:#0bl 7j~Dfc1fc 0`)XJ"1U356ݲZV`AKJ@ 7se 6eoCv/mf02kٔM\67D-cy!`JcXgMyvnE S#FY@ i x3Bl& n{zVUޫmn{ چΆ7.懪\c6KA Nc1͒?!Alb 06 H bfM)f& x#@1 ` `$Fn^q(Ƙ'nz󻮞t:Rj5-B2,\B aAbKo!qą jh[Jqy?=F`(c@QHE "Y1Ff*ە-H삲4l bE T4vR̼c:(jm|Q $ (BS.qMi"0M`gi(@ PlBP&@##06K1FD Q{Lfglho]F<X̙*c%YdjfecRaq@]뢟75.omk eO:{3 Smh|>" bpg1136,&ln TM}mcdCNboJz(UuTČ2\MmjX}leOm[ A}#f@)o.蘍 11ys[y##oXb64( F"__?޷ܷ޿_/G?0c`#`N> *4YR<1d&?3o~yÏ~_?>Kz:1,e__zG Ũ;Gg3 tngLث2>s&26o}51WdoB6 @fC5e3] ws { * moeX{I0Ƞn{m/-u!l q<2 LUa{V~o0b@mqÔh#(koH8X'2o PF@`lbPK/~|ǿOH|K\ .RʥtrR._:r\.Ν׹u:_NR.(QPЌ7eB^lyb fid쵷{3Y]Fz ?ÿgfgz=_ D<ٶƗc1ؚ %f|v<}|gmO{oƴ=E|xx Q6`9x }l 0eaKh{ƛ0 fW66x{o>{U9[f}٧nc>}mx`W>VM:T|1blj-mF/E~o0b bAmMeSFAQ6R6ELl:!#0"f}كQF Ȑ(o 3:@~׾7o//_O|%rH)\.w._\Υ\._\.w.w.w\|u:ND)QBefa{ОT f0Ӟ7lfAO ?_+ GƬ➮gLzwY}|y|7{6o6j3cl=o}>ogY߾ͼ)>sCflG8E3R>3=X4mW.ۛMYb)gSնUP=F}#e*ޔmXo[lP٪2knW "DdSZwKHH.(\ܑK)E #'D,E $ ӿ?PT7Hr)wwJ)\J)R:;RJR@e`l`+c$EN*CݱEYN+'_@շRt.fZ]*ũ[oyFIN2mXcdgAoGb%זQ*u` Dd{Q )tT+:T@ʦd TJG14OJt}ݰe,#}P6dg%6٪WC%^%%F6"t1R(1$(b Ĕ.!R̀ F% bX/|'W4l?ɏ?k?ٯ?F1""A06x1#}3wPQ{>6efx pY՘xP tw?K"v7_u썉=HNS*c\=%foFIWg;y^c|7./w6cGl01fZ6l25KyL*0AƩjQe6=ulu갭kXELq63GU{l  /}"a`ĠyFde@)2E1E<4r4 `~g~?o?a++/?=?kG'2e|@@D360Pf7VPͻ[cleTSiV k}}fCųؙ~жW 9F=[K]{sΜ3g/x.C&!D@PR]vmvTJ֑RT٤t5JJJJASc˯F\W?w՟뛯&}] (-<}~쥧>'B!J\W/)@q>?}JA$0$"@#@5D)BSPHVDBcY.o|ܛvIIT ݶ2Ad,+b&hH$PJO>8&ݜ_wlWaUcu9uexc5mRiP-,0YV~?ϽS'';3.yp#o+_w[46tt*fҶVWKhhBR d6]2"բE"іE% d&1Aid +KۮD+I2 -EiCh- @X lR%+ v-$P  QD$i֤$ 1D @ A"T#yم>( Fwv?û~7䭓Dh`Kn~0={gW~R~7m@p6EG PZ(jmR+dbUcbU$)6&H%-iP5G!lHFDU"ZE&[BR!ꦠ j^ާ_wX>x.:7{CǬc㊵9erլj- hvk \~ӯ?޻JtDm*IR$Z!T(j3hĝwm&e$1Ld"Lf}cDHJ"ֵ$YfC IU]M$ $IH2@dB{Lvdc1V PAW тʘ*ՙD"R)@!  D+H @4@PD݅ӳS{ H*$OW777WgHݳ"$Dbܝ~ɿr~~yɇD|ſm^>{f-*LRTP&($A% ش$$IɦML"h4iU#mA% eF14Rݲ*+ZEb5Ro/]s޿}~n&{zVN9{su׊VEA#`$dLEs+?3ӯ{ջo[&FWV"I$Vj!QRU2#VTGW2/<{| ?ƿG!-KNtXli$-ZLZIjl$#4-- I]CI& Mmt%h%H!%D0JR%RDA%T#h@J:m$ B..N\__n @!J"['K/]\H=y_{X׿?m[G!BPhM26$IU% kN,&J^$M4DV#Mjs$&telM'Ī"E+ͪI)"֢/=w/>x;''zhǵ~FYqñk-9fur/EJ2HO_g˯|m?w3w}+oҥ߼G_|ww7?Ͻ? "@ahBնT(B篾/?~t</.n%/>\GBd4ұ꒣m6ʰXIF 0Ylv4Q3il, aYI J"%I**@ D+(" AB B.@F)T+O m~^x֟âኂP $a/:91!B@[$i+-$j7PBiJAUbTctI@A5dt)I&A2*mHc43Vc3J蒨 ǰYKW$8r\Pժnۭ-znGG?Ǐ=XDfL2̘rzz*W*adtQ)g^/~"EhKH'.yO?̓Os/>w@#6*CMm[Ϝ$Go.zBӳ^~W>mw@ Y ee#aYAZ3ZV&Z mi$a@Z M[$`2DbB4Z"!:)HI$!Y$ 8'_|W~sn>%PBpDiZ-T9CrQ '"@$$HFh""d7PR Д$&))MubL:ڴœc6 eKӖ@(őcUJ>9;k7WWG3}ps?ܬþuد&s2,3m$=mm]DGƨ͌g]:;>s]&hշ{Oy[O>y^w{&B1vAdRh'Ek_]K"rv>z˯}~?H @X ڃ]X+jiApy~zgfwgnvg!IS%i* iA jQ+E"A98A*8@*RMıiڦwivg~׵H&m 2.PJH (!]dh52$Z4ɴV @jc JGH$QI!0 h$cK۷777Gx^|_OW@HB )Z$ m83.7!NG !B@@"H $ViVRdmf&PH #CFBc6daؚf6 19HmI&ABL2#l"f3g3ۙ`rM3s& KAC, Bwi_㫷޿~.j?Wlrvf&3-g$Vi3$ɳO^㩧],I3f$MJV9~I$IB4B Q!Irzg~͵&寝_Çz:՗~%U}fRJd $Ӯ d$! i!4 Q::C=6D(QjJ $P F ZI#PBP%QQ"U ^{şϾGo|_#=w{`f^xO}33s/ou A %  ) vr<~'! Hm3! Hh$%@A&I1  H2,,JXJ`h FLf$bbUIUm%H$R(0 Xр(BV1Tĭv]ӾZtZקGoNxi]_W봯kTb6LjxZuR$9>uq-oXUݶ{Osq $BE$*UxO\L"*V"~r{7_PŪI)Iʴ25Jhl,Tt1kuID["I;Ia'$iCA"JV$$$S92`(@%!TZA*$4$ QhR?諯~o2rF6>}߽>D(L- @InΟGh \=HwFV l7HBhi"!J%Sb&ڠE,6I&Ibt1]LSR $cۈDAvb ٬. Ȱk@TT\セُus꾎u}u9־N\i':.]6a:x|޾-}ʛ?ɳ3fi7xc׾Sޮ$Y&q:^Nǫٻv %,-=;@$xanf;g՞Tܣ-$I@( %J\q8]hjIw>Qgwygy C ekW&)"%̊0DZζ!] @a LFҮ$%JBѶ$ D+!T B D+V(O䥗_Ik߸9 C;}zoO~ٿZ93Qv;7MA[ tlMhHmH.o I?~)  +O/>s;E$HBݫoӃjYi D1TFd&ɴkXi:fY)1Pbjd(kY #j xǟxi~s:ޜniuoWRMbtj:]ZxZH.%t66 sO|f;\dB$4Ijڵ"b(Z"%=XosFM ]kO&G>Ǘ.n!V2!$qff&[+Ju풙 t5`(a@@( ZD%s("HI$Ӯ6PhQJ`QTL!J@+BC$ggg_z H @7}z{>SO"WlnM C"Ri$PM e;PAH$J;== HfҲc_mE$[DEI4?za{Cw9$#$$IT;/{Ī(bdA)!dX$CV04h(C`X5)Z,&&Ѕw?eyNu}}:zO7cVxëϞ?ygNփ7_\$xd;dU9lgk?uCL3,_쉔iB[XxEZ@"CIL q 4m1Q&rQ`;*Ldd$dm@W! ]KӉU".S23j@Y%@%m "UZ$C" U$H!bj &!H4[g>x|[:kѣo<(Z'ǶȦ$-P Z 1aL:[,1 Iej h!ڶsy߹ P"&I6/m;DɈ$HBBQɿ[xtRkPBZQP:11 jdU6]%#U:eE"MVb'6ɓ_s/\l3VjN[OݾW_O?ҳxZ_{s͒{39BQ=| -k}ǜݕPIZ((%Hpvz',UBX$ܾp}gk ^FڽH+وlLZ*C.J VJJF$JVȆI2ID6Ҷ* " "Z-Xڄl(@)<_޷_]sރǽĽs!(+W8>D6- CdLfƶ9;s8as8 @[jZ$IHHvTXV__?s33m69Öl[[ak\acٚfAlF&df2#Ib$I"!&B3(sù,c/f`z_'?x:k?"_~gǿIm[grv<-1gO?IZQh OKx:^ֱ3I&  3 >daܹ-λ7H6ْ-!Ȱ(ۥCIdƖ Lf$m$L2dZmV4 @ʴ m*$PPHdi602M[-!CX%P~ oW$ @W<*nnn! Ǯ޵vP `b5@D02%AZ6 ABUE(%^uqŌ--9l$l_>~˫mf'ŋ0acM&d)I2I$IDL"HFC3V4Dmms埼 ߾}?3OiZ]Ã{;?ݶ gnڿɵ}\dno,Vb;\Lg+h 3_}gomW1#CjE-I m8??! @COwA8ĘVWI[*H[-$6 @K$ IjX-X$IPڪVWղh ȡ E$SԊAHȔj$(+RT[yþ~{യ601$ NHn$@*# tY, DC HFUbdCd̘M"m@x<;;#(CPJw?+g l$$2[H|~=<} y< vᇟk{&?8ɻ3gol3|>_niDʐ6-_/=w#dhA3 }?=:AkB$ҟxtZ~Ђ:[}_>Ol]  ¢Ә"a C @і~I~HQB|?꫓$$-23fˏ72 95}kf>||_{i'a$kGݎwH$#$ I$A%Ag}mk]aN$?y^W>\ttp۶gٳE@HV ?7~fCF@@;<ܶKٶg;gV)pvv_}Rh[ax?_x{}.ՖDm2Idc#UH aI4.%PP$*Aۮ22A CڢD+]D+LB`lFB % ZU{tg{Jz߽̓Ky39}Ac_9w)!,"`́%elPԢTP`b6 d)Aws{|[_@  !Fzol "6I$mB2ӕl[vľy6?D"2]hsn8/]g?>>0:RP( ہK&HDlffm/# HJ (j0W_?7?^{GL@BgIBfdDfd${|1&M3vtޗSL-H $"IK.@6!>~dBAFk@[kl Jۉ]VS*hJ-@B"qNPKWgˌ_|?M'OWfXHcS $2h%mR%h%} K2 `ua %mPZ (Ijg۴ZB3FlRFHK+4$V@BhjA!!(ɹoOm'ǻG۹LJsţÃBB"QȎt/|0#"2Mx…A8Fi Jh: b>ݺu볟'^x FBȝ&Oܹ͛Dl$l̄[ݿv=ێؤb ߹{Iq("fZ̘$D+Y6HTv*QbtZе?mWlZ%_2-B[2Bh@%Z*钙ZOdYc*ooy^y/w>Z@ID єD4UHڧ 0D*MXڕ -aXBJTm"( t R I4&)Q@B@??/sWHiܿw/zƵ~DIDkvf^;ʕFFbb6[d3gJ JVa0w\ɝ_BW+tETڶd$E*tlu'Cj>>ͻ>x֭\>?XkZn m= 6Hh2$JvieȈi{J@mWi)C R@(EDdNF4 6 8P02, JhC A٦/xc2#ۭ{W/}ŗg?~ ˄pW^tƐ(BHJ@ V ("yW{玏6 BO~??ALdfg׹KFFH&=`W2$thh&%KFTJcP**eٓGۜ+*B*BDLA[E 4tvIJUG/;/vw>g~uLdk*$6RJ2R߯PW+TRPMh+IĶRR$IHHʴe$m!mdҽƠD@dcZI DBW_7k?zztttʵC%KnΝW^ ?/mAUZsw_7R1@ /V~tܻ ꫯ !D<K}뭷^}] d$9a$Bҙ`Jdfv3},)%mj@* TbDªKg>v|e۝iڶ.4ݛ0j- h5vje+ 5BUz|  &iXLړ&T"Z+%[hdm&ҶVL&muOZ&I$-J+ *JڀiYTՕl DD+Z Z1h %RM `7/}ƍѣo~GoQ_tv3}O!Jt}K#W?{|# bK_*!#Cd IKYuV*ZL|| ߹sW_C+iB?zӟ۷? .]Lwq1a4[׎wAZh,M TP(P" Ym V"]vqki]&$kC[VUAW@%vmvuRdgٟv6J+vE% thKZ]+&"}י)]KhUhEV;DiVfcXl$HlcJ@H D&i$$T$]B]z ߸<?z~J6>Kx'o}珎 PPX{=S7~x7g~>H?}=.Wg hZ*PU{ Jï_G@B!:>]|_O.^ztk?nޔiG7 ǹv-TZ #lA#ED+nEXUQR*d- 2_O=p S*Cig[I)I!-h@YV-Jv%C[F-VUW77m>{p>ݗ$mP"ZEX2Z]*A$i+bm"i+ dPHJ -@lŠVFɘJXC!ADa$%#IH aZ4M1^{>^g?xjWOΝ/"H(@b%i7}m<|{?_;wO߼_W?{. ThXU&2 @VRJ`j !>>JBBY׮Q|Rv͗F"4T@W/޻xKD0R1{I%A- jahP H5l 'Wv'(fkLA[UQ-h TKQѵ?{]2ZD֕ O~~mݯW~) *F0e&XMbTiɠ4i%*jUE Zb( !EH2dB%T#anH @0fd$;FFfۙlB"!j&YF)QPRϼ.^trrh[wB"!s[aBr#E?:!`˗~s_~yf XD(=;;I(ڟ?Z t!2Bl>'>~v4Եt '|O;_:|l! m11qOzA~>w{{8u]e$Etn[n ҟ£.[<Ͽhɠ9NeJNZ VsWv zx(vgg=<QakWx$GpJ_ώ,Wŝqn'6ٍ\uj Q^R $8F2fZB#-Rж,ŘU"U%愖ftNfztͲ,4[FZٓ{l]"Zҹnhf?cG'֋/Ϳ?g?Y$]' tQ0KB eD6c,]-ɔ*BQ mgm1D*@ n`ĈTl$jP!$Z(Fd3L$3$F +p$Xge$26aY$=eҀBCxz2.z?䓏>ןv wwOY-Dc(95Jc8pduΫOsdV_7;p9@wFB,wӽGgl::Y~3/]޹dddat40B`Lf2"DZR P!5AA(#&J09v&J^,-ThI-Pzw4 ]kUZB؜ejk(G=N-_z~~?yJ`Є 5W"!L"ѩtmF-ʐv6F[L$i%iHiIډdB%HFcĨV ("4m$!:GY0S bxGbR& H cc)C(B39ҵ/cl6;I1 >"Td7߹/ _x;7Vɲ|a+WZ׷>9 PHn9ӗwGyrng9~ҥP%P6fE3JZh BjsBb 6β{1%ݬ =7׿w~~v1 ed]QA3L l"کSI*#R$ SI s@N&Iih#X i#VFA1kF@hC@ Ph %E"Őh (w)lP*Q9̙ @@ Hf`登;3N$K8_x~{3gN?g$JuBAQ\=y;\!@$A+A/?[w'h Q`ٹz:~53Nq?:^'me?~W]XvRRBÓ,?YtDa2d(%1[VնjA@J$Z k#^;{/RV(c$mb-(HZm4RhIeI vGo<,7|勗~?v TJ:!lGd$,èιcdRږI&cmg2JEڑjT$i+-ٌ6LY %!LB@%ZTBDv&A@Т JCP%a̙ӧΝ (Sj Z pLr$}ǭM5-@ QT)dPr.'OD+QP 0'@ݞh{;}]e$ ZI Z J?/ndVc%n_}fOƻt^Wã%=e,wS'nasϼKb֠ztt[sJK{a'X^v9hj(I# :,ibjJA)m'DA#JhaV*tT߿uO>||7lR3HlYZ(6h '@fe?˾f%eO=wO>~饗e6g~ٷ{h%mH;%5 EAKZ3]92fd$-svmX\JF$Dj4 5M-.4IUÔP I6$&Z!h$F5QL$@Hf5LB4DÐI}t9ܿqS;K a@ 'zjH@69uIGV i2b3ʠ yx8Xz AD o?ywo I+)A I-Wt[-$疟K7nvQJA{3_|GH(Vnܩ.\?zasϿ<<^2w%J} ?}?'7]|]|\37hl'Ov 'w#szrp@[e-ݶ0""R  &hնUmiITZ!Ɛ(Ig1tIɃk:<|{} ѡYjAfN*òHH!Z-޲[6{cͩ9,A+!RA pr]۷}|| ҫ_+?W-#s2;9T҈,)Y舄M9'$mM+AuΒvM9g$AD[dZHd9c(LB@eh: RAJZDKZI(hJTB0$D0޿?rONog>W^ C(ĵ3gϯE'2]VFDh+2,1jlNYNYD$I-SD$?<~fd3g>қ_Т +8 ?y??=S}79?kΜl?uzgڟ'XϟL`sέϞ* U29%-S[ faLh)h(`j!PGW?On߾_|PI5P&Tfӣ࣏3y. ;oLYzfb}{K_N{NH(RP B h#M ;q4~;o~WxƳ{Ou߿tʲ,8wvׯߺEd ё"MfdA#C-bH e$cAIPVvH[I+(A$LF$ bZ Z:[BdΆ$UM H&F B @6B';|G^z}lko{?yH Eգ7/':NT" #fA ђ:{ ]a{$%RJ~3ݻ/쳟Mhp?9{?˚a06v+o\<},vjp:~xjeN?ݛ.ܙeYqzo${}p߼y|]7KڴJ[YI YTHh"ʄ*M;["BbH5 )40gKKmɇ|r鍫$J@蜩RD%{[ϼҽ^{~O>~/'|oã{뵋'bYsϽ1O_}Kvu5%1,jdiq#QSJ UM&Dg%2mHv06$ $mRFmdŦmB $J CۀHB D$4-MDhDQ]=78zoo7wjʟg; ZƠ%Dg2* R#f{sx_W( I1Wۃ?@% 2}_|]BRӷ>9FF}ٳyz3{KNYOu:s4y{.]Xlƶ=-qc nmK:U1[*"h &kVѪDgVID"jH!1Dfky/^{\vԩ=-dh %JbݚS%F,˃zo+/ܺu}^v1pރuoݛ$m?57_wW9svٜ{|tt$mDh*EU5dy+| ݽ{{w]~[dW^} CJ&vVSD'DÔf M1"V2VTh'$ډX&3i`5j$6fS5QeFTElB $BQ@I HBh(4И1l›۷o;vo}ևw7#_~a޸7 BH-ibDǐU `\^J$I-wDTC&)p87_y.~w/?3{{˲ңッ'<~nK9-1DH^{ܲtfYu 9ZyԌ{^ٳɐ0drRFr F&ڴb-PZHD("t(TKSvVad4@DT*-d誡DNR۟qɇ~K_Je"Z#:B[ny3G?cwew'?=r뛮_.;?y|;}ãۣKV( IITB($'=yX~ވȩ2*kD K$di7 ʀZycxakm†Fd< fUCw_?{y[kLC[on_[?~HCj\; m29%t SmW3Yیedl--XbN"3MI(&B7h2'B+ @Fڒ*BS a7ןoo_[_ݏ۟z a J"9[gL渞om+._]>8^朧.>=.wMlt$݈Snlw ̶Eu6)L Rj:u̚ajҮm[l sFͶ ВS s6!CBDKf|G~S"DCJK$)8ѧۏ>ڳ\F7uش Pd*|4>DEj2oeII!U*t6ѪBd-_D;)O=}x_":Wb4 :,sYʐ3KT B'II2&*IvV,2U h@h- Ia0QH-I$)@hh%HUe#)@c |sXOqw+w?>>4 U@ JI%0k 5”C(@bY>ΗI^z@[I>ysus$ Zh5TB Jyz}t%1lF'R Jcdz|w]:ir\\׏>Ni^]]_\\oo[Όent,#]nIO`{ܝuj٨Ȝh6P ij;ٮ4UFGi I"i) Ht ۋqvw/%IWw+ :F$̠"2K2GPchAYOG"QRIU z8O #XMڌ̶"MahKnWտ[r0i'!?ɓ?~wno^^ͮ뤈$Ct,CTLU5ElI SV-Dm$J"j-M&Y:4D BI:D+Q F"$$I J IH 1<{;|կߺu'O?U@Q!CQӜ2DC%֧.//?w} $˟k( J@9DLBhth$t\_N)bF(LdGw6fNkO9]a=~>9λ5:KFFf3gO!)[mnuvV͜$ mCJ-F4ۮ][S1 m[لI uX#4 I42 N&[Iqvk^ f 087h oNB)Tyl)# MS B "(&ytl/6ۻJIYivb/~owo߾$ٞ(,#w.n.nm0W^ٟ[wn߻~sz̹fI,@ی:kMmfjR:gU&2u$DMH$@B11cv&1*!E% 1%V2 1PD F%4h[gl?|ŋ/lnݾe3z:n/?׻?%M"mz<P (:%F$&!eJG_O}ܿ|ޓϟ IC&CP ĬP%1(׻ò5PK#JO>fi>0sғg{y~yw]ݰ3WjN|ūw$&6m'4MQ iHӜsTTm sFΞj FfU-A0sm!\2I 5V*-|F-J0gHBP03T$ dlEIP @pY6nƀTufDU~y}،o?^s9gxs8\/.o'ֵ!:PK\#H4f05-ڎ jV&aiOIÌDCA;APvV2ch *I풄n2M+Z$"H$-!JD u&4I!TF$F b>yyK{v6޾fn7gܜ7=Mnݒ]H[xP0VH#iDYs5P2j%'ݟ>׿:={4IO^>~a51 @1$جgw+T#Q9ˋ/ݷzv.XkL֎7J:xtv՚puNjzO|~f3~}e +k386,җf琖SΙ>/Pm9ݮSնm1甴^Uh[h2 V*zpW< ۷w6?i,hܽV?$:!VNBJ0 TQE e{. TEA%(@ӛt9? TTh%K^?x~FbKO:;׹*/]aߜ={_"Ԕdhv: ن2A6#LH;* % (*M1g!b#fmaVZ@PI[T D*QZCe9- :PIhۮB$H$J(eaN1T"Z 坟\rYq}\ a2$* 脒I$hXu_ JY!2z};~?toMOMJww9 檕IZչNϟ](BP }u\,^;V۶mDğQ Hg@&gg> />"iOd0,T_ѣwzs^:@ddˢsiV%Z-!2 H- @U(<<ۋhQ u$lz_}=7[.oݿ\^Osӌv]y'/&VEƂ+#"tDVY%CIUQ5)a$m"mLF;LjYBDRU %Ցm2 ! i3dHP jEK 1 !AFT jT1$IADcq~vi7 !*\?BHY K4HbNe@"(*JD)Wq!`jTR jj2(zVE2)eҪO7?|l|Inwn=?W^O9`tZww_7|Nu_w{}WGlZsv]Ot\[::g;OS'|vW4Q_ߞ~םm9wY&sVDQeZkOc_w|,/WW_]n+7>|$g/:hGb$s.o߻+m%YdiH$MHI;ڙhm;*BI&! h0 )lFaTH@$b Ɛ IF2"$DFc4YdɲȈXF"#$$#bٜcUN=^[oG%*0"(#"ef;ȐXƀPZ#H1$ >  $t{X " @n\c@罷{~!r{ӫ<̜:35lw|rg_۾zwvS"5ۚmVis O/o֬Қ,ufB^ܻn={ŋs6OyvhiDbPh괷T)ZզU_|r/7go9cnvwݝlKtR%،lΈ6cdl|;6[ @!,M ؝=XwEٲ5wiڹdl-0~ǻ_usݿ9yyWox|o}' ?ORUs8od%vRdJH*c@Bԙ4J4i+tRɠE$hBHDBc`,BR$H BH@D"Hd(I(Ch #2D2d$4! @i1B!hm1O:[IPH1cd,n?lha`Z-d- !!Ȱs':B"ݕH(at: CJ6.{ֽe|n]{sqQ$Ic6]~j^}/ŲٶhRPT P??h>ŅRZMœ:Sj~py4{<ܼx?zO?~ky{jĈMLDLPs?Ϯpyzyx<>|v|,K7G.oֿ?^}b06^6Ų,ʴ,*Nmi]36fYvlYΗX( &Ռ\;OA@DXdH16%mrz|l7޼y`|+>qs}O~s?~;Ke;$݃<},Ҷ2ѢRI$I$MSR4j$BR-@1FuD$)I*& IIB_;:;[i;;fӖhBQB  !!C"%?A֫bsrII⤥ !W{8A !"*T*P*R\%M۩{)S h%dȶ@AB#*҈A5MZ~x|JT =&KH1fDXNх9 A2 <㷢D%"2J BG@a!cbF~vۛs{97191_/|'O>$3"ID$Iw߽ݻ?{,z"Z҇'S֭ԲUnT]3&.$TK˿DQ*ZH~4? Oՙ]gTӮMV7ڄJ$EƇC%BW4IO)CUڶW[Z2mI8W}[q\^^?r7ٯ{?_?ɟ}~w={_//⼝)-q/~{oOmJh$Zn%Mg)% $ (@L-%dh)G Lۙɳ:vfP=RE$ I 3fd$JM0D`&yI$݊VI!tmo}zlVZUs縸ܻ~\qf'sm9jM9;nJB"zwqL.ЧGjMϯg?zA?{>-fO禛]=uٴ,=ug#ǑP%q&Cr-tu%&=~# =| Uj><-1hmw_?o'9r͛wI#2r!B֩IBYmmO`(iDmc h !MEh\R*H EW+t%UH$  $ 2Z1.#)Q@CD*h Ʉtdvl5j9\sO| 4&DsC:K jTi-P ZB!C@Pr'6*JICKhJh%(T&NB([!2b7O?l>|sۧZI4=h=CS_7Og>???^!GMP O|pZT[(|PNmJ+MZ!8t3I5*~]_}85vH {?y_wşٿO?~?{x)BV7VnVvIab8W7" U$<2C2@Lrܟ{a׮ICnoo~o?}17"1^.y|x>9sO>y{m d@SKM23hMdS4F %IV5V)%Bi$PI¨D)J$ɌDbL@H$$2DHdH$4 #)  d IbkV$DJJ m\r#s@r8$GcFK"C Co) @H;C"JJHh$PBi("HC?Grݳa\.^|<׻랣ǧ=sr>/~_{cdAy/姙#(R!R7ZvJ)gyB"քh5Z%uy1޽U6E;Oع~_{pmן~?˿ӓ6j+ѦMO{ڵFڦ5r926-*M͛wz??׏^|l&1zw^} 4l-$IBIBV@TFےdL 86I2ɑ$P\&*T&L"6MnwV %@HҮ J"LҴKDf."lMB#E)R$&nM@I'p0P Z@ (!Wy|#@%>˝VJ(@5R5[[!8+C +׷G蛧quǹ^̸rz履{wƈ Z;^xۣCJRE_~o.Iu5S-K]eF5~n4Eե'~'~yy~%Eg_~׏7֮]keJ]b:ijWhC Dj*EOwo AV-2$mZ @b[?7/gϿ~}>|x_~7W.c"\?~xp{:}oy{.9r 5I2IЕM6I@7RM-(IJT)%lJL+P#&qHSP!mJ#"$Z%HMLr4&I P -l3d&풶$MU1م*pn'P-"Um$%E4$\m&JBDH H >χnr' DJ$$BEmISFPh=[]}xy5xrqr\vчGJ{9rR8tv>$dKZ+~C_« ϿܤBqD3FSzhswhWl$|u~#ž_4՞<.Mi[k]=٤BN,eO]G1FKlk0iGyCAVZBv v Ю it*hӖ_޿xϟ~rp\޿눐\'_8.~듏_z|~'$V&N+P&h#n2,n{&l! mP۶MDHFۖ$!DB!TʦSHi\j DTAf03]6HB Iц@V. t+HMZ%Z22&1ښ!]KJ BJ`-(QgZ%J-B 2Dk&Pl J3O{yuMwvio9]!Hu38G$$K'+.)@((IOڻ\ܿQε]A2B>n_~ͷ|۽)bW *-$L^ڴr*mεժt߼zѳu>z_\>>ͳg}szw$ v7I;QvfddDM&TChIT:"DH#JJ0  BIBDepDZ&$  $ILB+"i4K$i6BB nMU*%Q&)eCue(TY@i%D DjF(Q0PB)J$JWcbZc,[EN%iΧq};9\8GqKJ1LLj$;w6m%DmհY/ml֦X'CYm/m:ҕs,CW/?<=cojRrvUi=X-me̮Vz.VD(nLao!QTMI*IKOE'iPJJ V(G-; JB&ӓ$oТ!q닏}g3<\wgn|~NЈ6 [*&AMpjUS$ݚhCI)Jd6@:6I/(IYĮDIB2!†J ##PBH%YMʌ -h5MQIEVe(ͤRm%@6@I @l8 % eZ&ZAVˀJ-eD %DPJ@ ( JbQ=e(%UDbj.Ԗ [*:ȭR*X%&J*(I@#g[N8׹ɞLZYRgDUSUO1L\i%+"{w7}*T*PP]-FF?Ayuߪꚞ 4EI ـb8ȑÆoȡ9K(0,8l=߬e";͝3;\F;e-sTC3wvh=w0c͸ӦގLlhs[ۋtٵ1fkR6掹sם DaB_~?;1`_~眍5fFݤ`~o }}x}}휾׏^]rwgGſB@mJ#v^ AfP{MYʌ؍3[Q4hMlbGP0bYBA&WwFw8AFul˙UQ6#bV\ zkoumC#ӽ^F##6'6#0b1b ?s۸^o_oߚڮpr؜L ×ӳ|vv>~~u·O||_s|Ŀ$HaNXs=pXkDc1""vb9oو FQLP 邆9m9m6 ݩCvݫ f]6U3LEv,6>g@ZCؠ~i}lN`,H~g>|hdq-)b&. ystt9v-;8Y޶guѼ&u{d2b냵͙.1ݽyfsfGyWfĸfQxx{_qk3vۻ3^1.c,L16ټ':IQ6 5g۞?"~!l^o?z}Ħ 0-kw?;pw_~ vkWrɨ-4iFvݔ r@vaBAb[Sm#:1!ecL)ՈDURmtjV*s}TT+iԫl1&3H(Ѣ@)Jy9G(}79cJ$$>{~ݗyj?wxgD0$)cK z)|88)e ѱ@Yd\,[;6ήzg3"]siPKh̐v5y\x{z{}l6]wDKPIĠ ֩̀Qfmy~wst|uoUD:,*ǟ>vWGwSd,]8\;|}Ͽoz;׾|?|yϽ~'?szU,`9JPpeT uTT(rTJQdX!btҵ*85W9a(r'ә-"LU\1۬-6e5!v1,<?o?~_돍aUM)c# v}_fg?ɷ@ % 0ͦr gN̝l^D:]Cʎho7ÇM_y' Rα)"l)`ۇ䧿_ǯ|x/Fb"b ĥg.3s,'x\Cv{?N4ϼ963qyfyҌט(ewwm.h{-4^=@yxټy^w>wy.s< Ff*A%.z}c{MP8קhؒS`]NfYͶcll~W_wOOO>o~/_տ[%lBOSry<2܍4)ӱ;!0`Fلlz@$XdL6k vrXBj3Re;Tg61@m ufF3pDKXZd>g_>pޜ7=~)1 `Ę/??|/Ӈ}t`iP(w;e٠,B1Ƅa JkDw6.Yb$0ձrNyfl޽ٗۻ>v>y}aL½[q67̮晸srߝzksY޿sog͕26*΀f9v1P2awl:)8J:?|<|۟nG՛EAmUk`!0@#i[&~_/߿ßɏ?~={;qvoS6`y݋י8۵:ۊ ͂]( Dtsrf+5M4:3(  V[8[Ymv:)w\*۔qlW96ӝa*#lW6bA~~'}lsr_bV珿{?|6$bӁ@|>x>=#f s)a;  %Ƹz.&̙gquleؘl?z=v|8{[v-Q2 wt̙ ܹSb<噯7lh=C $u֐0`b#祸$`[G^ @켾[jme,tSCa18m7n I3_~jIQ^"r:2{rcf8;lk iݭJj+]VɄdm^1Ɗ:9CUɮ(S4zcWa:9USՈ*Mt8LAʢ:'TO_?_~_y>>OΫwl[Ӈ+w"(M(@F_o@DD$bH22 fl /D"䔜b:Dв;xzfs}Ouؗsݞ/ǟ>MD[R6FF#F%)eٌ .%6f4*,u)g%"ssyLxK\ԧ뗽}«Ksk֖el-F1.¦l>^~;m_Ʊje׽s<P1j8bFF`  TG?g{^v[:6j3b2uQlf#5[RUSdg۽N0ZmjSnmccv&RYt%6M Wӡ1lrS#'3HbSMSbAŶs6:X*0Kd $3J `9Ak??|x^?}G|uXym?}?~/o?slds%P6(6c3Č1b;*c+̋*p=2k^Ep=l5z]wYBܹyfz8 se;ӹxVz{ĝ!X (V l &a1  d [ vO`۰ұ j]h"L*TیhXݣxqY@MGָޱ.UbsݝvoDBDMfMN@0ِԶvaw,u錶ӂZ3*l#NJ8.4z14R X_~Ç?^g~Ͽ~ٽ^g?O}W0<;6La( H FlP<MHӱ6w޸=^qyzصcu\< \ :^`\w3`.õfTm6{gfם<^ʹ|qoV^;f_1h *0l5 Cv'}A.?w=3d AEaeq\օ+K`aZ 00Lfzs~)d #lS1b|w@FvW`dSl˜;Mg8ePmJ6q)Gv!v:C"C3K3w4Xv1jd$g٬NئsC R2pc؅v%Qa *jKBcZF'{h.Шt7ۿoy??{ǹ;/S˯~ogoův޿{}?_'o./Oo(]"'a1ؠPPF` FF\+'8<݈qy ؃[Z;w\wFfk>ݹk{w6=v{];,S'|v=ߒkq^jl6YOw6-6ϙgc-`ՠ2ƔN{1`T@g][2F ;U+Fn#ͦڀ㬧ep;2k gVRݶte.nԹ:H6l∲z0B@T}aF,Fʞ'2FʮY#P Pu `[e a֨ mHن}q??|7?{U/a1v's;7O{zκ۽yzfs'[\,竻fsΗcmk}o^wm̽y6&Aq|۟/㇞ۓlw|_oGO/>}HbÐ1ڵu6=km{vr:9>v>Wt&Xfu:^[c^u{kם1 Iŀepᮓl 017Czy|qb,f eF&[\tz==nW3(wvoFZ}QA8өݻwN3lq\9]wcDlcP )pή ֝pXFb5 bn$MUݪ(!qK 0lj:m)+V[M]/~Ͽ$/W>|unG?~~9ϻ=//D^׋oϾo#G8Z{rb$0% 0C0#0Qb Bĭcww3褼kbGOϧ`l6nsof3̮'m]=+IKm>,w`.ó0sH1^Oڌ$[cP nq+,LوM`S61Дe'E"lDej4a]Q8eQڽYVn6G'.tl:`Xb1"ԨsakSG6Ű:#ƶg;6nѪ2[DֶSbv@FeLI;RgPcJ3U]2-d؞muX;/ys_|Kx|gG7{&|xy<_} ? wG}z|IX(@14wf,` q `pH;Y׮ݷb}z|Ӟo޾n3|E]s݅ʉiwSG=6y2[3mp-3fu's{]y^ 2c,$@@52`d`0 a80@8g4cf`Aú{tg۩mV ;aԈŪf'wzp{{sbq5Tƙ1H)HZKU`۶6/#Ғ]璂K`X^rd< `ȉx0K8.Vٸjs΋s=^>S|8=y]G?~{^Χ_x|}_uڲ;?7駿՗?/߼~-L3)f1, 0`f`l+{N4'纫{]Vxzo:"z~l /<ׇt;t̮aȽ=avc֞͝T̞ xk|O{^6\fin @!&cmXnf@00b Bڀen ô TmKc6mNgQcfOcwQ1b+u+n=NV< ̉1g,35[ 8mN<>͠R(:Uz `AyTlyGUh#CUvBF%|~;ѧzy9{}8Py]_f:bT/9o_ӟ~?w^}RdCJ#R "1 Hwvm dTQ?%?{~svݵkp<{mC-{_||ݹ}K?<|o~㇗?xsw?qէ篿__o/^~}"""RJ@ ؔ; |x$]Xgs_  i.{!k:|<yDNN}82w $AWv'kKEx1^MnNӖl0Q"j5(MJɂ10 YZ@AQ(RbhD"b գȬ-c#5AfUQ`d;g]M3mvN)3J R͘ljն@%)m뜹6jJH:AC 8TiUNMur ۤTH:Ju1VUgTtSs:QU%$sJ?~ٻ9;=^_ˇ?ow?7oS~~//8w?<||NAϿxw_^_?{[v8GA@Q$D0$$%;ad>-ژˏ}񻆵k]v=esikvk;5ڲ6A=ݹtfvExX[ˣ:96w02ɲ2[4aD@Fe@X(  `,`H@`L;jV (c[5j5K^߭WΛΓzW:z6qIw:UlusRJV&QٽJ,VKo=&VP׳/"#NcxZ00hn = n B0ۧ]+ykhfFdr\"!ifHfmD%"QFD01A5$1j$Jb&)$F2$ $Ňk$drs3^kz۹w}OgmO~۶gy݋Rg{<||ǧ$*>;͓?{?ϿG}G`p(Z"HEj l*A,@A VfF˃=x:jL$MSZڴNҔ*K֖QNJpImkwK+sIҵt)qjmڴZeEV-҂I ERJ)@ JUT((B QJ[ jR *mJͦEe'vΓ{ޑ%84ZĶˌl61e]tc&ݳ&Q鶜f:q$&](]$)VM̤m6Ifn+IK 0IDЙDdJ "d2$ D6 i7B$ZjDH(4Bj6ԟߗ){9&ݾ}z><{۝O_{y9>x'O7O{{{>>ge$7퓟D9x;}v_o?ԏe"2FhֆB@+QZh@PP@+zj3Fn@os:.9ɹVZUZ[hZ+ kHZQ}lL=>^w.yQKJ7]ꦴZjV 6JAA RBJBK B (EV@E(MX"UF̴RD@"I&Vd{ȶ#%&illg.Iݱ9t슦AzJI{%q̨8$&Z4N6 dXif*(vHA"LЖI:4 ɠMR0"J?t^qs9޼q1s;zR9o޾;{=n/$d_Ͽ3Ihy_I>}lOo$ k\7/5TF$–j@H!Z@ q>I>st3dd+ݍy$KHlmմM.{cw4I亊UjZPV)+jj)RFPRPPPJPH+   JQEPZڐЊ&lۈjmCIVۖm jϚh9Q-2&6(&EYGqrv6ˑt/\ju"13ڢivrm+6VLI" Hh3Da$i `$$IHJ-$LD$$t  $$IRLL !^\oQIr$&GF_ׇw㸼{r^f<߼|/O1'O??>].s̤o.Ou 0_Oy|ӏ_p $3BH/_^=佧\(E! TU(@=}1^'H/ǗOoŅDRi5!SΦIuuVjs]="BV MfHT`ӤUZ)ZV*TDQ-R J)(P6 JEZ@((! Hh""J Ah*4"*$"F%B2lYdiL Nܘ^ۓ5IQH$Z@4sHB\ZG2DL^j2Mt+ehZҶm֐&HS%vbMl$IݘLmLT* IAB%)TIUT34 mE>t~=yx2<'}ӏ^>nz}xog?g|_3!_]6Yf_O?c^A%J@+QB#`B {Y^?ƻoo/Ǔ׮D%Z(h (@ɦϛ'T$!>9.vC9 5MMNghA:BJۍ5l1cӴԖJU4*ݨ* mڔ6UTA@)(R J)(U B@$M( P(%@֦J@mж)j蹛 k5Bm[E@$ I5H8WHՔdV[iٕ4n̹U<mCQdh7I䱮¾=" \fe@I*h3G**$I )3# J$LUmTSD$B2JTR4MC4)H q6vz7o'`zWОǓ|W|g~˿O8$3C͔btٳLJA%tWIL e#O棏>^/r{߾&pZh@(9^J677'XL(+t+IBLF( vDjDmDuenBF[ mcTBAAQmRPRJ)m&@Q VBQ((@QEQ m[FƮ 2=e*StډFjRT-T5rF`TۤJPЪ$M\{TOΌM"689Cudwer&HE*vK1m(@%VҶ9RٳJRBJh#$6$BI;wyv9铛[^_G^~w$s~v|޿9.I0TW_ xxgyHB ѦH$Z"y>?/~۝'Ճ:Y%#` @P4}]z$Wn_q斂-G2)M8#e^ٙ'*+mUBF*dZVYֶlHAt-=U** PJA)RRjA(%hP@(*@% ( %і0&,h.=nfI,LҖnAd,1FVuDn$鶓i+h$mM\<@Z)2(ȶמ/ *(VČYBTvdB)]+QMZ.kWO h.HJK)I((@AAA"!*Ia)h BE IVI#MUUʆdi$-'̀j;V)vLbеiTtBLcѢ $99&MܵGJۤIZ;s\fYm] ݏTC E2ADQ,!D3!$E23fF!`23IDH$0 $$Ӗ L&$;?:xl2$G?is||r{}oϿz]8.cr\hxN}ݻ?ϟJ$fDD28Wr򸽾xWOn@ @B|<H'?O(A6m*ZJWۿJjfkWV6j-]n!VVDb44ivmhA$(J)XJ)R J@PB R $4iI J@A2BٖbwڶR*mu D Uc$:L)*$ 8jN$ IT*˩8 1G14c]2\BHB4D6̴m J і$$PI(T&!L"A2IJdt2!$$$H$!3I"GO~޺vhrg&!G.q$&nf\.1s\.q$dJOt^r<w{{'ߙW_s"2f(HBW_ӯߌKϻ 0y]#@@ps7ED%yzp~m "*TڵMkZJIZ[]h*Mu7mϵM!LWkl'"!F"HJ T P J)( P R@ )aD#((V.$ Mt$$V544R! &mh$$H$)$QE&kIBrVc*#bV"!ʩ% F-$ChhkM2)TRd:!G[TJ4T%I;IV4ђ&BA9pΓ{ӵ2=5I {$7fhLLH2 IV׿r}gOw>zs|yw[}޵VUswVdK06q<F |r[. Cl#:Vz>UZ?)( h- 4B PJ(Ba>@@ [/Ao>}woOJ( J@e2n۟v֪-@Vin%ڥsc`6." TKJ@RJ)(@)( R "Re KR H$Iiے&+.lV D&IDZlv5Fm"k5iD V$h[ZI\13tC84K#!ɪXi`fm.I&CD[h@-ZIj5I&m*I%%baDiB[-!ІM@54V1TE#Pive-zHt%c I$]6#aIX+֬ڿ/Okѫ]'ǻ>KҒ&IUfVbR%J(`!!A _}{ݏEBA@ixnEUPR A*"TPM>Ӯm{RRPm%JRP" (@QP*Z jT EA)N(BAU%m%4h&c5ɌuMvժJZB;$h1}Bv@&mӤ:z<..ْI3k_\1RHZI[Q~lta&TQ%1hMT!Zۤ""D2kX4ID-a$M$3Ju2B$JH RM3!eU}}~~FKI3dL6*+3VݳׯϾ?d- tHXJZuABJ(bŕH{r"BysjVg_o[ ,()R2aYZ%!YtYJ$TUQ$h%((R PPP PP(DRE!U D@A! RZ`6҈mJPbz FIk4 CVW2mľ֌jdu$MvhSBgclmZΉ$M[@m?7sۙn]%*JFvh&BkdUQICIdlHH[0ɒZbP"&cZ!I i[6L.,6HW/v6fe=}8/I3"Um vd#3OncodתDP CY V$@ 0"L[ d>,@ -jw^>}%G(),#tOD)^Kg[F@ @J@ RP J)RPP -P T.@h(B@ @ Ю$]Ltua2]mi3 b-51I]M mZm %U &!Q4U+uds8L}[LԅLH6("L$A&D$%iL$3SQ#ifRIhI$i$9fH$I$B$hH2I"I&D&$I}7\dۤ"fbThBն*-mлgi><;߾Wᄑ[9%"6!ZV%ZA H ! Üo7HHf8$Ag̶#sQ(P@)*eQiCrS)sCm\?! Z4EQIRJ")RJA R !(BH@5 !@P%"MIb&jT HBiDb&$! DDgFI"$ ZVt4g2ͤMr]&9 dHe]:uhI63$ E+34ZU]m@I!"!e$$I(&1m!-""uu;{pݖ)$"Z&m$W7^|leϥq9yGDd_2m۶mvVĿdn}x~X>}p_|?5VK~yqw}}wr|}%@@xOq'$% Zvz\k}B(h/>~/D@J P֢.cJU@!KVQT@WhhۤPJA)-4J)(,@A (4 4PP@ @%ZeP@ Vj%m@-IJ#m$U%ʰ:Ҥm2iC"ѕL+Iktde%P4-LZm%GDe-Bދu;lz~ye%y U,:ߞ Pb-ZIi%T%-QhMڤM%$I"ZkUI H $"Um`ݛ{Q&B2m2kݺyfr<:ܦ`zw(g.'9~0Lk$_]z|z7ͺ^\݃N'$$ Lnf~8O%v^LJ% mFBS RF$* BR 2IKDZZ$$D"/z| Lv_~UO7VDJHOywk{=_Mg\=َqد)Pյq|7><>f3.ݘսk%b;W;~;_~䛻9}/jf&s8ld77vu^WoooPBɳ;|{?ìMx^={R7<>>~4tJ*A_zӋӓ7mU'@PZ@ JЈ*)(.B)`Ph+A&j(RP P}z`ӟ^7G?|; P%h;IԊ( P@A$h[ J+iMUՙ*h &e2$Ym2JlV}zz k%iGD'K.:nzY׵ZraͶ1kny)#/Nקgvd%fs}||srZ+ & a( JB%d,&bh M* It (G˛7߿{{=}_P H7~?Nb]/O|q}| Ҏu<n>\)0&nNO_}_zy<[iw3mZ2y'V޵ZI%f2x{{s:m:z>|ӻ͓2 ((AOy_~Ono麮6D>=u=_yF@@JT[(M%)QPEmm-iET+RR P@BA 뾮׽]OV~O=۷V@芠 (FDDH6V*$ڪvɬV"IъvjIE(jj#m#m:۬.~7U;m?hΌB[=kHYznosnHOcz9ۡϟ^>q<ξz|3$k~S;H')`ƢMjB" LdȊh&BBHI1~˟$I d.w?:=yO7/>=|'ϟ}YkJc4ڵh2kٓ~_/˾wö=<\nn.z=Ͱ>_^?]hz~޵d2ٶp<mL2x</'?}7Pim7v,YnߟE6ݶ>wklBJlzvZ/.ON_<]olyݠPH@[QZY-mVٓ۬鰎ے^Ǜi7a5ZimI'Κu,;Ƙs~Z{>]]U,4aCq aGHeTU|ߜsẐ# @`’m 872xmGmƷKͯ_Oc a d B?}O~xbI`#dK $ @( %aY F@%= Δ8t}gFBIJvvF|BG=r;ETLm蟁̼\DhY*|k ~פ\KL0۫ߜôHJm]jZjcWG%Bd1HA $ض,@H`[ `$B@(Tȷa}x*$d%FE 8R˷?~azx*]:߼*ȏqۢ5$5$Rnx|u6i o*U`Q?>01r#,۲%"JVK) 78l?wmy_ؾ{yY^֭}k?7eenc[^?3xijs<|y[׿̥^:3J<9,K-77gn>x|o_I^K^Ǵ1F$`  $lK.1Nts,2sY[[חqmO_=^1Xl ``  d,jۗ_qOuuS&ѳ V?~u߶=ǰ9)tvߴN=~y*iH !dm@!Jq+f-[LOſxwÅ>#ו>0H!TgM%#@HCb2O+c€%ـt:$a#I8L) *˸=7KγZn1x_6% ]C9%G)hoӷ]nhS ҮuYG ib?/m>>]yM*u8K&qSY:m:z)J#$kW񦗰p!P ׮5 )-r:No^jպۛyzOO~S(e`]vR\!Ws㩗˨(Qd{xIQH J0Rjkx}˫0ȡFvV|}_6?aϗr["|z}?Oo.e>J1/ZA >JwS]rzAUA ͭƳ6umn[7H̻s>;{>OK||emQ:U /yV#n;._]O\߾Ski_.1ƺnÞ΋k˷/3\3w??mtVNO_}8>>>qTD4x0-7>|h%l)9 "Q }}@}1>q:yZDR"0jáSiM^>FӐڶcL.!1Z,r<̿i}){,#1 &$[>zQq9sYkE#3mVKiRlӗo7gmj}gb,N[Ps~Zr}yz=o޾zZڗe·R-7ߴ%3~>L[]xSۺ1䢔F!""P""bhvKi*v._ƨ,Q%`(E!Cd~ٴ Fqe$Kny:o22ӝ7ߎsYݗӟ.?=nZ[P"-eZUޟ-.kܾ;eZr^>I^Uoan?;ju1-KyM޺mMΞdyiR҉H; BA a<{[u?4e;;(Q<{qT:K i__?=m훗_770ݯ\vs v{m]$H(ev )F-VZl_fٞש\m.vܝmP8c=,_^~Rc =B[(o^e+iLO >a14Tk_.?ōy{țӳo_[9"}m޶dֈBkrZ)!x<~OOø5@}OҭZ2t&c(l<}y<ݟn~iw%2isx+F !ru57Zx0:HL s;F:m{qennnN77iken#g$>:KxuKX[d$l bs~ͫg~?q/)q Ї%T$I% E*3k ܇F81#C52.1j:LZ*=v)ywZtd|p٫ƸúA4Iv69 cBMm aIijF{#ȶ"J-1yiSE} F9Z#TZi-b%lm{GJYZ 4n̷q]{1fv 5ީ>e&ckݳe i}=q-NEzw.VYǩ^ݟ_ƞ.QTj‡rw~z;/^NKmcvztoiH$0D(%J%B `lp$$(m.%IpԖSTbP$ XdI8"\[UB^׽e9oSk)m@vr<m1H"m-gꮽ}9Vp8,R$E1K}dV" B2UIzȩki JS-007yx\ޞ7wl5cADZT\^ H>͊!jdm.vG*gf) PZs p z6Hن\sxqhZb@N5l+07{岯{J$2"Balmݶ}}؀AcAOg2O\[+%tv$ftRIơ۶߶ܗ6ԖOdz]޻m`8IrZ(uxzu݋?]tmOScy{WݗӴn=>~aYvƶ}11^_,o[92K Q (,H*$GX]݉qsB.<5-Kekk\lZymϽ޽y;FRH؊"d$X*}1j,l}4ϧyAm66SۗGJ|T)MKuR6 6igY#Z{NS-Qb$ IR##4tH}$F"9f#1Cmv}9FFe&ESD^׽ A{fH¶9 };331w;B!ijǹ죻)G4x#,VtvFr(<1ؙh 2{۶gi[ ĶZS<-Ԧv[s>rŬk$x{]g"aMSBRֲL%dAISKiY*%;?/U8d`әcAm=X}]123 i6FMӼaYsb?\5z޷}b˺Px}xً{-EqfFx4(Bmj#GL5Z0LMj60Rې]j%b )"pIݙ!$ ZkRJ-Hd}u^j<#""J ےlARtX}GA.Dzje `'Cx-5m+V ۶IP4!C2I(YQ|ZЦ\3cʁ0Gkȋf3-ey.HLg툰=cۚ&4(RQO"C I43=ǨsL}\޻10 @IRKDm-CJ*2 XRR[-Z0S1 ` ((’@BRC@c]#Hٖ$ (dNEt:K)-D>L8GLZD i3ِ91zO#I5CiJZRZ: L)'! ; {p )DI!Ix>ϧxH!PV4Lhz}}>^@]T|s~~~_ϯ__?ϻ Q9 i9!ѰЄ"I"Mi*m.__?g}SIOy>~y w0΂i9ғ+^ɉ#8^}CiӤ{oڒ|>*$ <ϟ?|<yl ~~{_gc+y>wK6eOr~x*{{N>??<<$M? $Iv[5 ;Kq&ir}7[n7M[9I@ *ntww6)Ip( <ϯy94=9m^I~yߛϯ믿~uZ`{}{ϟۂ'S<*I}'9S/~~>tGH9|~_6&$ϓFlS7̛m޶r! PMl~{/Ir+w<~~IғIڄ{zN ?I@kwNw_?-xsׯR` wv D;e&}nMh%}߿S9$ ${&IO&Ҷ)'pRAh}&ޛsN~|o699 =ǤK%I(Py>?~4?_>'awImS~Ͽ${}9's~r9{Ӓ>y~OZEm [Fi @P):Iサwﻻs?ս{<=<'O{yHs*$Xx6AE% 6y(.^'ldQ ®;)VI i&QQ+[Cu9O$$mzfL nN%M|PIK҆$I8AhFIlK; /2E VEts۞$Pl۶v$ $᜺sz6u۝;ew* $9m$6 DHB :'^wTi]?99ϽoQ$kOPSED(ɽށS}ߦO燂g{{y½#j;*#Kel*{޻wmIL&` is=mH$ Ndw&kFhK5 #:"$I II9I";{^'};CDŘ Stڶ/$aZӐ is&$M$IYaw}{//z{}T7U@QI& I!- f$ HTTtwm{}}/;{޻m7f[wa)8S$$6$;Q$ImF QM! V! Hz‘ݽKŦ"\$6DIs@{$Q $BY< H wѥH8&nTUTSu3quw}}}{}^WvZ"$I)Ph (yU,۶!K~zRIZu^ z{ n^S76!ITs ,iB& Im$'A $df!S&T@ @&IנDKt5P~Wt|_MiPԙ !h:/?MaS9 ̏$ kBU6m cKJFln:TUTtMթn޻w}WbD@ƹW%p/v}y{oP9$$BT?OOJc^+ pl-AyBjJ|I@ML@dn i[z$/cUxtsNfz{Ω>u {sy#ݻUU܀v`A40wD mNO9' wh$-&MImI%8Imjݾ;EEMlK)&~wnEH BS" 6Q& iMi I"6ICI%I-wSQ@iܴ r:wMwW gʙ mUt~vB`$nBӂӨ>͖9gN+:msoT@ImN6!eCғM  '''M0M$'IB{pF6ir^ rpymK6 kꝉrwmQtwn9 BՙWS Iڦ%'t7iD$@^vƚt`tg[$e&E?Lw9T@ O'rZv I$ !M(Ess眶=<;VȽ=ٽbHzڞ& ;vH@Hژ)ysN4=g&4$Im$&M@6jB :zzRÙ'm41$s座JQa6mq$d't[5)I $@II $ȝۀ4wK8- 6@&BiѐJB[aX;e]pnۦ*NB[5 EdY.IBNˠ9ORrJIL $i!#K^]bVf&5:2ԤDr i&! # K$M$B66mI۴M ږI@;iJ(Cs!!$P@(M2@l&QBŶ@E i@Aw/%MRH&Ф" ;JP$AA*LHƫĄ&Dh).I$6% $ѧU@]Ƃfsw&ʶ-Rt I$I4!-IpIАE 5osڔDrtu y>?{tS'*IDd{mޫJ$! ?wiI$I^{s%4M$ $IR mH$MpwI'e,+X,1@CŞF.mdm{m޶-ߛ+ݥ~ݥ.UOsw]Mwww]ױ{{{̕+-~{~{{{lT]UU}}_]u]W{oo{o{~o{mカキmmスm{nM{޶0VUw]}_]UJwʥCE w몮$uQu*O*퍽YU}f{{}lfEc{϶6eĈaۺ޻~oSuvvNw7յ-U]=޼_{y{~޶mal{6JεҬu<\M ޸ߴ{۳mmذl{͛*Ķ͵z˻;tsr4թ*`۔~w[Sj뺺0=dۛ{~~sOoo=Ƕ7 LH֕Uݮj骬6jV*m u3(oж{{o{k{om{bV)ʺ.w}wT}}u]WUww]u-o{=ok{޳^{6۶=c[۬[%)]!QV]!oytW1PU-skvwEu]uwu6bĈmaݶm۾mg^{^|{o_mjͶ6~{lWw֙޶uw޵i6.l{ofm7l޳ٶM{i3{Yt:hU% %E+Xl3ü\?{ݻ4۳6ڶmm0T 6buᄏKwݕtwѤWWFٶqgL:26۬{zo=nf3emզpUUۘժgw6S΄jn޼n{=1BI7nwQm뽽m{7޶yc^okmf{{mHURN% X<[g QF@ݽJwuw{kvm׻Uo[+ ޛ{ݝӷƽv޻yo{o{{[`Ɔm*`V^ٵ1sAŞm{=y{77͛m۶m{mޛ޶E0ZEqy{w)cSE&p }}Ͽ~~}犾m {o{m_m66w**UJa}n[ڮ_U/u]TU_Wug]2al*$B{g'oϯ{_9^K@Eɶ_J %cըh0m{ޞ{{{{{m{{޶!cڔθiuS^ުfmom{{fom{{}mݽ޼˿l Q؛TMx<(Pm;qW;=qknnsrsv+z=bam^y?7[of޳y=o{ݬL}oo7{{سl 誫TʝK>KRXWٶ͘myrέ=owo3yXA6ۦ]uWUMUt۰J0l}w}?OϓNաN ض7ml`X-&*]UW'UUSʪRUuR] Kcm۰=!' mUF۶mn=b۶ sPBJD%5#?oj)]afh77[\^7wٶF]"Efi^Miaن jUo^ s߿e[%AhPۊ*hsH0n\jWuպՕ:kLo*3VM1mig۽~lf3R6w69UEUUUuW]uwU]NJov϶gn^mfm썽ٶmF*ж&HW꺪*U:! rUw߾Q+# (6*6yoo3X*]*uUU]WUWUUUUݝ`K,U 6mlCro?Ym%(T*6T6H*ɩL%Ja! r36~[o[~{{mlæ~ ux:Օ]Whe^{o3c]67fn3FJ5 չ*E U}(Umu]BFʖM6{=0lQm4lk ޶ $ʶTж** MbQ+B% I8U^zl'k*'}fgm6ۻUU]d{jWi^)U,R.o^m[ۦ=fmf[dަliiB]WLITו$)V%UbK{o{j^1j 1@Rm 9fflۍޏ6S1À] *uPTUuStfضmlب@At0f̚?6TN U$mW5d۶mΈٔM{>ۋRWkf~wjh[lIUUV_wRQ=UժNm[Xi1f@lR=fMgTHB NJU!X1(V*kAFژK]6&^=\m=4makT!fuj]mUv^u2̲o 66ml^S+`6mmJ2{TUTRWU JVHªRBpLKj$F4l 1b<)۶)lo6uU$UUQJRNT5l[5m&[EmcLM0`66!HP]QT*R$!e[ynoG 6f>=xmZ/?Vnf:G$uWRNHU5*&Q@ MZ#l46i)l潻mx6ۆ 6 l6 tHF@.Rlc[1\ Ono{6oiv QiF8aرc?wuqitj;Mӈi˜uZ(1MQ>%O{%!h c DhI$PI%QBgbpWr՚kt,.Nmǰضhm!D$?oG\rӦMqիZ??C^}9c&#wk ƅiaaJ?5F2Oˋ.MBfDܿs_~{'"ЩeHNE3IH PhI*h -҂hE;"U$H$I1"$IDP jiJ Z4ђP$ MH H @$9$%LEA%-m+@@ "!R(JP1U  0:UF-$JI E @@@Vcb$Jl߾yA}{ߴ]"3 MA+ %m%k֞k#I*%SiI1!1`L%ٲde!DJBb S%V6#4UUM |3_yOnnֶmKFfD[B$A$y衇?tלv{oOf%zO~>9c 11ܘ%c5fIfK`w޾~OYzM2Q֮oxc R*t2hmH j * U*R DР*TU*-J@$ $DEi;-ꤥ-ښTmv$mJ@+ $@$A hs A$P2@A -) 2""H@2UH"P I$:d 4(p ?<'7o߾e~sa4T@' ¨J K:0AJ;:HN5""$*d$D H "% Ogo};yЁyi˖-cd&~|}l^Ofs9Ljm1;S߹/~~#)x{wg\^u9zHć'%/>?'vr۶$ں%/h?Ӯ3>Ci;MO~z̭LdfS٠2;W]s[.Kef,03捥0c XJ[oY˜:2G$M_{>_{]wU?gug ?y;.ڴi|=~Eܸq?۾ ߶yG~]pZ@ (J@H  D%VVUE H A I$* *D#!  "$ P@ I H)*"yƁZx[yל/NL\,h;M}GWz;6-ݻw&ђ\/ٳ}U;w\luh2w=bxlliZ|[ⴸaf{oWZ =7mͷ}q?-.6sO+֮6sc4[fV^u'?#}<@ fP0죎o_z$#@1|/_.ȺuO{嫟[c60FdVZ}!_~YK`l򔍛w}!xy{{`T-Ѓ]@=w_vN=կzN= y}~GImHNz9s^sKO9+WG}իK>CsݵT5!0??ݻX~;v\ oZ\ܼ)P<pםێzwݻv`hZGw#`ɒ%wyǽwuexo妽{oظ lٲ#~m;۽k]w޾k}{}W?`=O>#?cߋ<蘍v ]~ّG?wɒ%87oo=i]n/_qaG\wݻ'}5[<N=?_.wߵoϞ}{> {Oqs _ ޼}]ۯGsW [{,d67r"]|.Yd 'Ng‹~gc䨣{_yαc6_{_.[_|< >/ǟ1{ֳz/zׯ',c^#.[<֛o&y/xl6N6l:%_A8NҶ׭[֫ϻ׮[w֣+}'?C;gmw  6iWsoxۀi}䑋??AJ`dIPz]O] ޤ]s@,y}޽h-uy;Z@x?~ ~q i P$( @QH] BHIoWIENDB`aqualung-0.9beta11/src/img/metadata.png0000644000175000001440000000427510612341731014751 00000000000000PNG  IHDR szz pHYs  tIME-tEXtCommentCreated with The GIMPd%n3IDATXWiPTW5S5T&&T9UYTFgb" iv @ek@DvAdӦnfGfAD8ԈI S5]u{~}7[`-SE㸃5} 6_s[^bzt] 2D =wҽ:|cqmk'zPmG+Q^]US z!-RL {[$=`;'Dq]=(T!=b92Eȸ(ù RB>2."CCv ;U\f>yӥ4' q)G `3w@0/Ȑ+A¹<$e"='yW5=߇&\#IspRjKv{x_X#11bq>t ;Y胠!JDBz6::I; JHf<8 vZm x&<MK_FV' ZȫTXt.֬ۈE fNӌKjdKV mHOg>쾲C؉0FN#/禟B+֚sߋ6{iDr]$d^^MmÍ[m@u]=y56#mNذ~Kl5cG$@whْgX7o~>>^/?W< t[w`do^Kߒώf4K@B5`emZ5J'wwK_?;/^TjLFSf<yޔHLҔ m`-qIB8$ДauSIߪac+̙2ߟz3;u]&z::p>|(r L8hcaIX2%ύڒMHJ)zOU^BHƷ!8ޫ` Z=# `W0,JBL(=pnfMyGPu,xQn!ޞ y%e"#7nPb2CLQכa aK2 x 31%ΤO=t_˫0H"c70'}{,&U4HF]/m,l{+lG88K!2UnI3IͷP1<40-8[Q{q7J/DaS0YNbwBO7_qfoZ}ju.|('/>[ zWIENDB`aqualung-0.9beta11/src/img/ms-cdda-nodisk.png0000644000175000001440000000100110612341731015746 00000000000000PNG  IHDRabKGD pHYs B(xtIME 92@IDAT8ݒKq?y$1C)$ơ'kإCA:yJ9;%"СP&ZKw![5`l%ovHL><`YV$Ryӹ (Oc qYd2I, @kqZ/ڶ]s/-esSB@*ai{}}}ibr;lqj|% iݻTWWX\\D*g5rầ>Wֲ3.APRP(hhjIJ,044$;S7H2YXu); ]l*F\ᑷEe@i fM0bAsdcccqa tv_ JnOxobl6 xUA4xO0l?e.>!>!\,͡:XAiyo:RI_':388߿]C)nEZw"\w':>8:>ߗH_.fL@]A;D"BHI6K8yű<&a,"m. CU\Ug;ng#~nqV/\KRL*xX ,<WJX'%(@Wɮ|<+!PW.>a4AFkH2ӹ~5اIژ?ㄤxva x iDUp5Np]S?'a;mq[`>XN.H'0)pe: F yDW/ÃPnm?_#M؎u\iUP`@`tS nd7O&b|,9zczBѹ%@gՇ,[Y)sťum -p$:v߶ ?1oz{߉c\ wZԻs”oʧ+!WBV+6tREO6'IORy8b+`KHcQ3zRZ<`K"iFUy>\OFIENDB`aqualung-0.9beta11/src/img/ms-podcast.png0000644000175000001440000000106710664635361015253 00000000000000PNG  IHDRasBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<IDAT8}ҿKP{5$$ AmAIQKE"Ha5d?֐""hr+{n-EdUv텳}s<֪юA\>"oqOkXkP8{ {0t5Lskj LfB?fql>$B0̯AL? O9\"xmU?.p 3@aƩFqT`Z4GWRT_'3+ZkZyv$_~rKDe SvC8wU^& 35:1 l/o9k#NOkS? FqqIX/e‘VQP#D= loq{GW0ſ"b{ϱcx̼񗠅yAdžvǣfn5L:D&IENDB`aqualung-0.9beta11/src/img/ms-record.png0000644000175000001440000000174110664635361015073 00000000000000PNG  IHDRabKGD pHYs  tIME'2xtEXtCommentCreated with The GIMPd%nEIDAT8eOhe|4&͟&i6iB H4TI=JгE[,5V֛4Rz0mjDUbJMvٙP*y'xlFORi.B[ڎs/֋U#Ǐ;5940c/@KGyĉ~;֟߬T"2p.J*"!hnnaแɎY---}߃}Le!l T2iY U 9zrt+{ٞF|"|Gޚv`д\c~E^L%HƉ%PCI8͝;|…ߖ|^NOOauˎūk2J5;HF_.Dw`˗}0:rMJЋn_=RAHv~oa<֛G766?yBkmض]Va*o`~~>S>.NnIENDB`aqualung-0.9beta11/src/img/ms-store.png0000644000175000001440000000154610664635361014754 00000000000000PNG  IHDRabKGD pHYs  tIME(%|ztEXtCommentCreated with The GIMPd%nIDAT8˅Mlu?m/7[H+춆RH$&@ QVx4 pC/6D {#6H!*iAC"H}ggvf8('|ϣԔKEGSm۶ADۆ!Wb zTпoݻvuZkTT.W^yȑ^:ayy[?Hum 8@H"$LRoW+ O ޛ7G B\V l&vZre@K0d$gR9w,1ONgţu(uj4|<#yk3IZ:3dejIL!%Bp&x 8v8It>i#4| l#<$BdTDz4MA0D.OKDBG*ㅽFsiq24bpxKV.-m~~|g##(p]W >Q-ӢVh487ǡÇ8qC>pdpyRnh^I>mrìUWBJ$24)OMȰ3~H,fP! 0%ɲgi#OL&"aH_,F1d,=) w <k51I.RJ[_~^׵oJ}IENDB`aqualung-0.9beta11/src/img/ms-track.png0000644000175000001440000000064410612341731014706 00000000000000PNG  IHDRabKGD6Mumy pHYs B(xtIME YH1IDAT8ӽKcQ_40bةZ Ŷͫޟ!ւ w{h`c#ڈ"+dzgAA4r枙3\mb,^p$$,a[TkZR^&L>PsӥRi;ކřCoP(8IEVWMZUor;˝_WIENDB`aqualung-0.9beta11/src/img/music_store.png0000644000175000001440000000467010612341731015524 00000000000000PNG  IHDR szz pHYs  tIME+ZEtEXtCommentCreated with The GIMPd%n .IDATXõWOiUhV&^c& lK5^ʹ-eJKr*fs2ÜOac ma`evV7<[o%Œ݉M%gk,;xeժ=TbN ~' P}M~"֞Ib\? ~ F'_Y;*t9(Aϰ RtL,y|tHg VDn|@6;#/H ]B9F &'Ptkk+0MJʪb7^ Tj zvchS=%z#n'^O TLe @9gsQ%qtPS(͊A06՟DY#΢[(yv~ԐBWa%@?/ְʀ2 Sm]4 dr9fnFgTa _8B FG!aii 0eV+fqA9gb5\RAbGB 9$S q/#"{q] JT*IQU~2~tqpvm$-f(O!E󝞵c^XdsƐ%22FY,PQe<4Fjkٺ#Q)4 㬋oDjyү;FIyI^\_<#Wt1٦Y*Ȭ3*гN ^ 3_AieG,eqqjv7["mPz2:~ #ҒT!O=SY|dBCbi%0(U0 i4 [$SEJ} 򹏇2{e8kwgcSV~񄜓 <q[(i=(-$9yH(9^u')Q}GEr3V+Lf3+7>}NzȚI $d6,;%w2|>L탒/}/7NU+(1ύ W 얛^8]P:\|PFﰂr8nDW@3Rͅ%19e i!@<%# Q1'd#wMLr뜤i (# "ܡEoٯw;: NϘpX,o@L V9{yߥNS"O=%$1߀)}|i\o+$E=ɈiK 쿶uIENDB`aqualung-0.9beta11/src/img/playlist.png0000644000175000001440000000317610612341731015031 00000000000000PNG  IHDR szz pHYs  tIME*79tEXtCommentCreated with The GIMPd%nIDATXWKlTUwfn;3}LL ҇P[ BZ| .H4&jbXЅ6Fb@  iK M>`܇9wa 7?{?wOܤ| 4+H$}&9^B+Lxm'" SAm 0K )nIg sWHO{3Hw9.;Bsa G&̺ـۡka0t:Ǵ4uGM;p㊍[ "zeC3PsƧ5&+9i~P X]EGGhG|T*] ՆX41G0V/:| 87_=Eww/Byvqgd_^  <<=NbɊbs=dtg%mKWѼyE)M5yFN:ϣvc`9NjL<7!6ӳcpd?P`<lS3Q0[ω)4ߛG@|HyΣaEq82r$ jv @,;0ҥTN1 'ȒJ39V®˜Õw[ٯ=W9W 0zY`V8:Xjk/ތǐ\DDb ^'^G^E>lc=~-cFa%lx{;bkMv4B#YW˟ +g밦jM#vO()9Z#v @_ag3g{P^"/&f70l\[DSf$ҡ$,[0c"Z z4o1p33m}',zT=':pȱb-شiB>21A2r(DŽnl $b$ J^X ' `&!ңL%@D x㷧k <8{hokr v~>/+kiE-eI׸"ϹuB. [gsIQ. t]V#"};S\Pl*% 0׀3xD2H]ϚeB" !.M#n'a}`0)ZRhDD 9:f& 65Hkk=D `clAGZ$-FRnfCpg$"!&n&xCo[;p݉9lcb9t]]('P tut)uuyMTz`kF:J^ +eY>@\d.B*\I*9P gTIENDB`aqualung-0.9beta11/src/img/rva.png0000644000175000001440000000313510612341731013753 00000000000000PNG  IHDR szz pHYs  tIME+9WtEXtCommentCreated with The GIMPd%nIDAT_TW9ޙ.]JY@Y m,M*M)lYV hbExF(ٕb6DS*bbc ҇& ,]vqٿ3;kf6Yyh>VǎC~nɉ;wC:֮}Ə=mg{~SIؐ|_Ϣ/O { XqxښBm|@ٵ֓ٳ,҂|8˔X#6?Z%ΝWyЏot-'3>w'o#޾tbay)hJ@ҡ=Fyi` pOz rņJk%ձ MMaO|r-Դ6._鵫hs{7lhw< Br9$5k<( ;aځg 6j'?$PaAMȭ)HxpD ]+ma^yԕ4F@aC〔77pW,Q PfyIhhnh)ƣ"@M$ҐP)&`1"x)J)"4ڀiPgPkc*'J(d>@*+L26r(g )gy;AK5pDžV6xUQ21X2$6AdW䥣G㗎X*#xkJ"kR֩+bgWr>vФS"UZ:)'K$ORIdz 2fi À9|ʓr Qhrk(*g ""B\,O15sF E&^/:G*. LS 4Myyxfd(;CUڐZ(,QRKw% f[(Iʃ8q5=Qxg+f9;C쟛W2 (H98 RGJѢ4y f/{\UT*Ե0+M-?鏨9p1j26ᑫ"J1*=JHot@ a`.o~!ĉ@$9!֗ pUH|ѭoX(Z)E*RäF>߳^k?ν4U։w\Bt|@_;}z8~$J;̡梾02$y+#CǞziЫ%\m=Z,Ú׀jIDATӍA ],"2.‰x^܄2O+A8eT f!DIENDB`aqualung-0.9beta11/src/po/0000777000175000001440000000000011331334363012403 500000000000000aqualung-0.9beta11/src/po/README0000644000175000001440000000253510747423146013214 00000000000000Creating new translation ------------------------ If you are willing to create a new translation, first obtain the current message catalog by typing $ make aqualung.pot This will generate the file aqulaung.pot, which contains all strings subject to translation. You should rename this file to XX.po where XX is the two-letter ISO-639 code for your language. First fill in the header entry by replacing the uppercase words with sensible information. The important thing is to set charset=UTF-8 in the Content-Type field, and the whole file must be encoded in UTF-8. Next step is translation itself. You are suggested using a decent editor with .po syntax support to make the process easier. When finished with translating, send the file to the aqualung-friends mailing list. We will include it in the distribution. Note that you have to run `make' and `make install' before starting Aqualung in order to test your translation. Updating your translation ------------------------- As Aqualung development progresses, some text changes and new strings appear. Translations therefore need to be updated from time to time. You can merge the changes to your language file by typing $ make XX.po Now you can edit the .po file and translate new strings, fix fuzzy entries and remove obsolete ones. Finally, send the updated version of your .po file to the mailing list. aqualung-0.9beta11/src/po/Makefile.am0000644000175000001440000000210311331325773014354 00000000000000DOMAIN = aqualung XGETTEXT_OPTS = --keyword=_ --keyword=N_ --keyword=X_ --no-location --copyright-holder='Tom Szilagyi' POTFILES = ../*.c ../decoder/*.c ../decoder/*.cpp localedir = $(datadir)/locale MSGFMT = msgfmt -v XGETTEXT = xgettext MSGMERGE = msgmerge POFILES = de.po fr.po hu.po it.po ja.po ru.po sv.po uk.po MOFILES = $(POFILES:.po=.mo) EXTRA_DIST = $(POFILES) $(MOFILES) README all: $(MOFILES) $(MOFILES): always @if test $(@:.mo=.po) -nt $@; then echo -n "updating $@: "; $(MSGFMT) $(@:.mo=.po) -o $@; fi $(POFILES): $(DOMAIN).pot $(MSGMERGE) $@ $(DOMAIN).pot -o $@.in && mv $@.in $@ $(DOMAIN).pot: $(POTFILES) $(XGETTEXT) $(XGETTEXT_OPTS) $(POTFILES) -o $(DOMAIN).pot install: $(MOFILES) for i in $(MOFILES); do \ lang=`echo $$i | sed 's/\.mo$$//'`; \ $(mkinstalldirs) ${DESTDIR}$(localedir)/$$lang/LC_MESSAGES; \ $(INSTALL_DATA) $$i ${DESTDIR}$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo; \ done uninstall: for i in $(MOFILES); do \ lang=`echo $$i | sed 's/\.mo$$//'`; \ rm -f ${DESTDIR}$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo; \ done always: aqualung-0.9beta11/src/po/Makefile.in0000644000175000001440000002223411331334254014366 00000000000000# Makefile.in generated by automake 1.10.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # This Makefile.in 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. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = src/po DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = SOURCES = DIST_SOURCES = DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBAVCODEC_CFLAGS = @LIBAVCODEC_CFLAGS@ LIBAVCODEC_LIBS = @LIBAVCODEC_LIBS@ LIBAVFORMAT_CFLAGS = @LIBAVFORMAT_CFLAGS@ LIBAVFORMAT_LIBS = @LIBAVFORMAT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = $(datadir)/locale localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ var = @var@ DOMAIN = aqualung XGETTEXT_OPTS = --keyword=_ --keyword=N_ --keyword=X_ --no-location --copyright-holder='Tom Szilagyi' POTFILES = ../*.c ../decoder/*.c ../decoder/*.cpp MSGFMT = msgfmt -v XGETTEXT = xgettext MSGMERGE = msgmerge POFILES = de.po fr.po hu.po it.po ja.po ru.po sv.po uk.po MOFILES = $(POFILES:.po=.mo) EXTRA_DIST = $(POFILES) $(MOFILES) README all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/po/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/po/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install-exec: install-exec-am install-data: install-data-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-exec-am: install-html: install-html-am install-info: install-info-am install-man: install-pdf: install-pdf-am install-ps: install-ps-am installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic distclean \ distclean-generic distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am all: $(MOFILES) $(MOFILES): always @if test $(@:.mo=.po) -nt $@; then echo -n "updating $@: "; $(MSGFMT) $(@:.mo=.po) -o $@; fi $(POFILES): $(DOMAIN).pot $(MSGMERGE) $@ $(DOMAIN).pot -o $@.in && mv $@.in $@ $(DOMAIN).pot: $(POTFILES) $(XGETTEXT) $(XGETTEXT_OPTS) $(POTFILES) -o $(DOMAIN).pot install: $(MOFILES) for i in $(MOFILES); do \ lang=`echo $$i | sed 's/\.mo$$//'`; \ $(mkinstalldirs) ${DESTDIR}$(localedir)/$$lang/LC_MESSAGES; \ $(INSTALL_DATA) $$i ${DESTDIR}$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo; \ done uninstall: for i in $(MOFILES); do \ lang=`echo $$i | sed 's/\.mo$$//'`; \ rm -f ${DESTDIR}$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo; \ done always: # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: aqualung-0.9beta11/src/po/de.po0000644000175000001440000021470011331334210013242 00000000000000# German translations for aqualung package # German messages for aqualung. # Copyright (C) 2004 Tom Szilagyi # This file is distributed under the same license as the aqualung package. # Philipp Überbacher , 2007, 2008. # Wolfgang Stöggl , 2007-2010. # msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2010-01-13 00:15+0100\n" "PO-Revision-Date: 2010-01-13 00:16+0100\n" "Last-Translator: Wolfgang Stoeggl \n" "Language-Team: German \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Poedit-Language: German\n" msgid "About" msgstr "Über Aqualung" msgid "Build version: " msgstr "Version: " msgid "Homepage:" msgstr "Webseite:" msgid "Authors:" msgstr "Autoren:" msgid "Core design, engineering & programming:\n" msgstr "Kernentwurf, technische Planung & Programmierung:\n" msgid "Skin support, look & feel, GUI hacks:\n" msgstr "Oberfläche, Aussehen, Handhabung:\n" msgid "Programming, GUI engineering:\n" msgstr "Programmierung, GUI-Planung:\n" msgid "OpenBSD compatibility, metadata tweaks:\n" msgstr "OpenBSD-Kompatibilität, Metadaten-Kniffe:\n" msgid "Translators:" msgstr "Übersetzer:" msgid "French:\n" msgstr "Französisch:\n" msgid "German:\n" msgstr "Deutsch:\n" msgid "Hungarian:\n" msgstr "Ungarisch:\n" msgid "Italian:\n" msgstr "Italienisch:\n" msgid "Japanese:\n" msgstr "Japanisch:\n" msgid "Russian:\n" msgstr "Russisch:\n" msgid "Swedish:\n" msgstr "Schwedisch:\n" msgid "Ukrainian:\n" msgstr "Ukrainisch:\n" msgid "Graphics:" msgstr "Graphiken:" msgid "Logo, icons:\n" msgstr "Logo, Symbole:\n" msgid "This Aqualung binary is compiled with:" msgstr "Diese Aqualung-Binärdatei wurde kompiliert mit:" msgid "Optional features:" msgstr "Optionale Funktionen:" msgid "LADSPA plugin support\n" msgstr "LADSPA-Plugin-Unterstützung\n" msgid "CDDA (Audio CD) support\n" msgstr "CDDA (Audio CD) Unterstützung\n" msgid "CDDB support\n" msgstr "CDDB-Unterstützung\n" msgid "Sample Rate Converter support\n" msgstr "Abtastraten-Umwandler\n" msgid "iRiver iFP driver support\n" msgstr "iRiver iFP Treiberunterstützung\n" msgid "Loop playback support\n" msgstr "Schleifenwiedergabe\n" msgid "Systray support\n" msgstr "Kontrollleistensymbol\n" msgid "Podcast support\n" msgstr "Podcast\n" msgid "Lua (programmable title formatting) support\n" msgstr "Lua-Unterstützung (programmierbare Titelformatierung)\n" msgid "Decoding support:" msgstr "Dekodierbare Dateiformate:" msgid "sndfile (WAV, AIFF, etc.)\n" msgstr "sndfile (WAV, AIFF, etc.)\n" msgid "Free Lossless Audio Codec (FLAC)\n" msgstr "Free Lossless Audio Codec (FLAC)\n" msgid "Ogg Vorbis\n" msgstr "Ogg Vorbis\n" msgid "Ogg Speex\n" msgstr "Ogg Speex\n" msgid "MPEG Audio (MPEG 1-2.5 Layer I-III)\n" msgstr "MPEG Audio (MPEG 1-2.5 Layer I-III)\n" msgid "MOD Audio (MOD, S3M, XM, IT, etc.)\n" msgstr "MOD Audio (MOD, S3M, XM, IT, etc.)\n" msgid "Musepack\n" msgstr "Musepack\n" msgid "Monkey's Audio Codec\n" msgstr "Monkey's Audio Codec\n" msgid "WavPack\n" msgstr "WavPack\n" msgid "LAVC (AC3, AAC, WavPack, WMA, etc.)\n" msgstr "LAVC (AC3, AAC, WavPack, WMA, etc.)\n" msgid "Encoding support:" msgstr "Kodierbare Dateiformate:" msgid "sndfile (WAV)\n" msgstr "sndfile (WAV)\n" msgid "LAME (MP3)\n" msgstr "LAME (MP3)\n" msgid "Output driver support:" msgstr "Unterstützte Ausgabemethoden:" msgid "sndio Audio\n" msgstr "sndio Audio\n" msgid "OSS Audio\n" msgstr "OSS Audio\n" msgid "ALSA Audio\n" msgstr "ALSA Audio\n" msgid "JACK Audio Server\n" msgstr "JACK Audio Server\n" msgid "PulseAudio\n" msgstr "PulseAudio\n" msgid "Win32 Sound API\n" msgstr "Win32 Sound API\n" msgid "" "This program is free software; you can redistribute it and/or modify it " "under the terms of the GNU General Public License as published by the Free " "Software Foundation; either version 2 of the License, or (at your option) " "any later version.\n" "\n" "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.\n" "\n" "You should have received a copy of the GNU General Public License along with " "this program; if not, write to the Free Software Foundation, Inc., 675 Mass " "Ave, Cambridge, MA 02139, USA." msgstr "" "Dieses Programm ist freie Software. Sie können es unter den Bedingungen der " "GNU General Public License, wie von der Free Software Foundation " "herausgegeben, weitergeben und/oder modifizieren, entweder gemäß Version 2 " "der Lizenz oder (nach Ihrer Wahl) jeder späteren Version.\n" "\n" "Die Veröffentlichung dieses Programms erfolgt in der Hoffnung, dass es Ihnen " "von Nutzen sein wird, aber OHNE JEDE GEWÄHRLEISTUNG, sogar ohne die " "implizite Gewährleistung der MARKTREIFE oder der EIGNUNG FÜR EINEN " "BESTIMMTEN ZWECK. Details finden Sie in der GNU General Public License.\n" "\n" "Sie sollten ein Exemplar der GNU General Public License zusammen mit diesem " "Programm erhalten haben. Falls nicht, schreiben Sie an die Free Software " "Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." msgid "Enabled" msgstr "Aktiv" msgid "Source" msgstr "Quelle" msgid "CDDB" msgstr "CDDB" msgid "CDDB (not available)" msgstr "CDDB (nicht verfügbar)" msgid "Metadata" msgstr "Metadaten" msgid "Filesystem" msgstr "Dateisystem" msgid "Capitalization" msgstr "Großschreibung" msgid "Capitalize: " msgstr "Groß schreiben:" msgid "All words" msgstr "Alle Wörter" msgid "First word only" msgstr "Nur das erste Wort" msgid "Force case: " msgstr "Schreibweise erzwingen: " msgid "Force other letters to lowercase" msgstr "Kleinschreibung für alle anderen Buchstaben erzwingen" msgid "Regular expression" msgstr "Regulärer Ausdruck" msgid "Regexp:" msgstr "Regulärer Ausdruck:" msgid "Replace:" msgstr "Ersetzen:" msgid "Predefined transformations" msgstr "Vordefinierte Umwandlungen" msgid "Remove file extension" msgstr "Dateiendung entfernen" msgid "Remove leading number" msgstr "Nummer vom Anfang entfernen" msgid "Convert underscore to space" msgstr "Unterstrich zu Leerzeichen umwandeln" msgid "Trim leading, tailing and duplicate spaces" msgstr "Vorangestellte, hintangestellte und doppelte Leerzeichen entfernen" msgid "Regexp matches empty string" msgstr "Regulärer Ausdruck entspricht leerer Zeichenkette" msgid "Please select the root directory." msgstr "Bitte wählen Sie das Wurzelverzeichnis." msgid "Select build type" msgstr "Wählen Sie die Erstellungsmethode" msgid "Directory driven" msgstr "Verzeichnisorientiert" msgid "" "Follows the directory structure to identify the artists and\n" "records. The files are added on a record basis." msgstr "" "Folgt der Ordnerstruktur, um Interpreten und Alben zu ermitteln.\n" "Die Dateien werden auf Basis der Alben hinzugefügt." msgid "Independent" msgstr "Unabhängig" msgid "" "Recursive search from the root directory for audio files.\n" "The files are processed independently, so only metadata\n" "and filename transformation are available." msgstr "" "Rekursive Suche vom Wurzelverzeichnis aus nach Audiodateien.\n" "Die Dateien werden unabhängig verarbeitet, weshalb nur Metadaten-\n" "und Dateinamen-Umwandlung verfügbar sind." msgid "Load settings from Music Store file" msgstr "Einstellungen aus der Musiksammlungsdatei laden" msgid "Build/Update store" msgstr "Sammlung Erstellen/Aktualisieren" msgid "General" msgstr "Allgemein" msgid "Directory structure" msgstr "Ordnerstruktur" msgid "Root path:" msgstr "Wurzelverzeichnis:" msgid "_Browse..." msgstr "_Durchsuchen …" msgid "Structure:" msgstr "Struktur:" msgid "root / record / track" msgstr "Wurzel / Album / Titel" msgid "root / artist / record / track" msgstr "Wurzel / Interpret / Album / Titel" msgid "root / artist / artist / record / track" msgstr "Wurzel / Interpret / Interpret / Album / Titel" msgid "root / artist / artist / artist / record / track" msgstr "Wurzel / Interpret / Interpret/ Interpret / Album / Titel" msgid "Exclude files matching wildcard" msgstr "Dateien, die der Maske entsprechen, ausschließen" msgid "Include only files matching wildcard" msgstr "Nur Dateien, die der Maske entsprechen, berücksichtigen" msgid "Reread data for existing tracks" msgstr "Daten für die vorhandenen Titel erneut lesen" msgid "Remove non-existing files from store" msgstr "Nicht vorhandene Dateien aus der Musiksammlung entfernen" msgid "Artist" msgstr "Interpret" msgid "Sort artists by" msgstr "Interpreten sortieren nach" msgid "Artist name" msgstr "Name des Interpreten" msgid "Artist name (lowercase)" msgstr "Name des Interpreten (Kleinbuchstaben)" msgid "Directory name" msgstr "Ordnername" msgid "Directory name (lowercase)" msgstr "Ordnername (Kleinbuchstaben)" msgid "Record" msgstr "Album" msgid "Sort records by" msgstr "Alben sortieren nach" msgid "Record name" msgstr "Name des Albums" msgid "Record name (lowercase)" msgstr "Name des Albums (Kleinbuchstaben)" msgid "Year" msgstr "Jahr" msgid "Add year to the comments of new records" msgstr "Jahr zu den Kommentaren neuer Alben hinzufügen" msgid "Track" msgstr "Titel" msgid "Import Replaygain tag as manual RVA" msgstr "Replaygain-Tag als manuelles RVA importieren" msgid "Import Comment tag" msgstr "Kommentar-Tag importieren" msgid "Sandbox" msgstr "Sandkiste" msgid "Filename:" msgstr "Dateiname:" msgid "Test" msgstr "Test" msgid "Building store from filesystem" msgstr "Erstellen der Sammlung anhand der Ordnerstruktur" msgid "Processing:" msgstr "Verarbeitung:" msgid "Action:" msgstr "Aktion:" msgid "Abort" msgstr "Abbrechen" msgid "Unknown Artist" msgstr "Unbekannter Interpret" msgid "Unknown Record" msgstr "Unbekanntes Album" msgid "Scanning files" msgstr "Dateien werden gelesen" msgid "Processing metadata" msgstr "Verarbeite Metadaten" msgid "CDDB lookup" msgstr "Schlage in CDDB nach" msgid "Name transformation" msgstr "Namensumwandlung" msgid "Reading file" msgstr "Datei wird gelesen" msgid "Removing non-existing files" msgstr "Entferne nicht vorhandene Dateien" msgid "Unknown disc" msgstr "Unbekannte CD" msgid "No disc" msgstr "Keine CD" msgid "CDDB query" msgstr "CDDB-Abfrage" msgid "Retrieving matches from server..." msgstr "Empfange Treffer vom Server …" msgid "Connecting to CDDB server..." msgstr "Verbinde zum CDDB-Server …" msgid "Error" msgstr "Fehler" msgid "An error occurred while attempting to connect to the CDDB server." msgstr "Während des Versuchs zum CDDB-Server zu verbinden trat ein Fehler auf." msgid "Warning" msgstr "Warnung" msgid "No matching record found." msgstr "Kein passendes Album gefunden." msgid "Import as Sort Key" msgstr "Als Sortierschlüssel importieren" msgid "Import as Title" msgstr "Als Titel importieren" msgid "Import as Year" msgstr "Als Jahr importieren" msgid "" "Artist appears to be in all lowercase.\n" "Do you want to proceed?" msgstr "" "Der Name des Interpreten scheint in Kleinbuchstaben zu sein.\n" "Möchten Sie fortsetzen?" msgid "" "Artist appears to be in all uppercase.\n" "Do you want to proceed?" msgstr "" "Der Name des Interpreten scheint in Großbuchstaben zu sein.\n" "Möchten Sie fortsetzen?" msgid "" "Title appears to be in all lowercase.\n" "Do you want to proceed?" msgstr "" "Der Titel scheint in Kleinbuchstaben zu sein.\n" "Möchten Sie fortsetzen?" msgid "" "Title appears to be in all uppercase.\n" "Do you want to proceed?" msgstr "" "Der Titel scheint in Großbuchstaben zu sein.\n" "Möchten Sie fortsetzen?" msgid "" "It is very likely that the year is wrong.\n" "Do you want to proceed?" msgstr "" "Es ist sehr wahrscheinlich, dass das Jahr falsch ist.\n" "Möchten Sie fortsetzen?" msgid "The email address provided for submission is invalid." msgstr "Die für die Übertragung eingegebene E-Mail-Adresse ist ungültig." msgid "An error occurred while submitting the record to the CDDB server." msgstr "" "Während der Übertragung des Albums zum CDDB-Server trat ein Fehler auf." msgid "Correct existing record" msgstr "Bestehenden Eintrag korrigieren" msgid "Submit new record" msgstr "Neuen Eintrag hinzufügen" msgid "Matches:" msgstr "Treffer:" msgid "Artist:" msgstr "Interpret:" msgid "Title:" msgstr "Titel:" msgid "Year:" msgstr "Jahr:" msgid "Category:" msgstr "Kategorie:" msgid "(choose a category)" msgstr "(Wählen Sie eine Kategorie)" msgid "Genre:" msgstr "Genre:" msgid "Extended data:" msgstr "Erweiterte Daten:" msgid "Import as Artist" msgstr "Als Interpret importieren" msgid "Add to Comments" msgstr "Zu den Kommentaren hinzufügen" msgid "Tracks" msgstr "Titel" msgid "You have to provide an email address for CDDB submission." msgstr "Für die CDDB-Übertragung müssen Sie eine E-Mail-Adresse angeben." msgid "Please select the directory for ripped files." msgstr "Bitte wählen Sie einen Order für die eingelesenen Dateien aus." msgid "(none)" msgstr "(keine)" msgid "fast" msgstr "schnell" msgid "best" msgstr "am besten" msgid "Compression level:" msgstr "Kompressionsgrad:" msgid "Bitrate [kbps]:" msgstr "Bitrate [kbps]:" msgid "Artist/Album already existing, not empty" msgstr "Interpret/Album existiert bereits und ist nicht leer" msgid "" "\n" "The Music Store you selected has a matching Artist and Album, already " "containing some tracks. If you press OK, these tracks will be removed. The " "files themselves will be left intact, but they will be removed from the " "destination Music Store. Press Cancel to get back to change the Artist/Album " "or the destination Music Store." msgstr "" "\n" "Die gewählte Musiksammlung hat bereits einen entsprechenden Interpreten und " "ein Album, das bereits Titel enthält. Wenn Sie OK drücken werden diese Titel " "entfernt. Die Dateien bleiben intakt, aber sie werden von der Ziel-" "Musiksammlung entfernt. Drücken Sie Abbrechen, um Interpret/Album zu ändern " "oder zur Ziel-Musiksammlung zurückzukehren." msgid "Rip CD" msgstr "CD auslesen" msgid "Album:" msgstr "Album:" msgid "Rip" msgstr "Auslesen" msgid "No." msgstr "Nr." msgid "Title" msgstr "Titel" msgid "Select" msgstr "Wählen" msgid "All" msgstr "Alle" msgid "None" msgstr "Keine" msgid "Output" msgstr "Ausgabe" msgid "Destination" msgstr "Ziel" msgid "Target directory for ripped files" msgstr "Zielordner für die ausgelesenen Dateien" msgid "Add to Music Store" msgstr "Zur Musiksammlung hinzufügen" msgid "Format" msgstr "Format" msgid "File format:" msgstr "Dateiformat:" msgid "VBR encoding" msgstr "VBR-Kodierung" msgid "Tag files with metadata" msgstr "Dateien mit Metadaten taggen" msgid "Paranoia" msgstr "Paranoia" msgid "Paranoia error correction" msgstr "Paranoia-Fehlerkorrektur" msgid "Perform overlapped reads" msgstr "Überlappend auslesen" msgid "Verify data integrity" msgstr "Unversehrtheit der Daten überprüfen" msgid "Unlimited retry on failed reads (never skip)" msgstr "" "Fehlgeschlagene Leseversuche unbegrenzt oft wiederholen (nie überspringen)" msgid "Maximum number of retries:" msgstr "Maximale Anzahl der Wiederholungen:" msgid "" "\n" "Destination directory is not read-write accessible!" msgstr "" "\n" "Kein Lese-/Schreibzugriff auf den Zielordner!" msgid "Total" msgstr "Gesamt" msgid "(audio only)" msgstr "(nur Audio)" msgid "Ripping CD tracks" msgstr "CD-Titel auslesen" msgid "Begin" msgstr "Anfang" msgid "Length" msgstr "Länge" msgid "Progress" msgstr "Fortschritt" msgid "Close window when complete" msgstr "Fenster nach Beendigung schließen" msgid "Close" msgstr "Schließen" msgid "Unknown Album" msgstr "Unbekanntes Album" msgid "Unknown Track" msgstr "Unbekannter Titel" msgid "Please select the directory for exported files." msgstr "Bitte wählen Sie einen Ordner für die exportierten Dateien aus." msgid "Copy" msgstr "Kopie" msgid "Help" msgstr "Hilfe" #, c-format msgid "" "\n" "The template string you enter here will be used to construct the filename of " "the exported files. The Artist, Record and Track names are denoted by %%%%a, " "%%%%r and %%%%t. The track number and format-dependent file extension are " "denoted by %%%%n and %%%%x, respectively. The flag %%%%i gives an identifier " "which is unique within an export session." msgstr "" "\n" "Diese Vorlage-Zeichenkette wird für die Konstruktion eines Dateinamens für " "die zu exportierenden Dateien benutzt. Interpret, Album und Titelnamen " "werden mit %%%%a, %%%%r und %%%%t bezeichnet. Die Titelnummer und " "formatabhängige Dateiendung werden mit %%%%n und %%%%x bezeichnet. Das Flag %" "%%%i ist eine Bezeichnung, die innerhalb einer Exportsitzung einmalig ist." msgid "Export files" msgstr "Dateien exportieren" msgid "Location and filename" msgstr "Ort und Dateiname" msgid "Target directory:" msgstr "Zielordner" msgid "Create subdirectories for artists" msgstr "Unterordner für Interpreten anlegen" msgid "Create subdirectories for albums" msgstr "Unterordner für Alben anlegen" msgid "" "Subdirectory name\n" "length limit:" msgstr "" "Unterordnernamen-\n" "Längenbeschränkung:" msgid "Filename template:" msgstr "Dateinamen-Vorlage:" msgid "Filter" msgstr "Filter" msgid "Do not reencode files already being in the target format" msgstr "Dateien, die bereits im Zielformat sind, nicht neu kodieren" msgid "" "Do not reencode files\n" "matching wildcard:" msgstr "" "Dateien nicht neu kodieren,\n" "die der Maske entsprechen:" msgid "Error in format string" msgstr "Fehler in der Formatierungs-Zeichenkette" msgid "Exporting files" msgstr "Dateien werden exportiert" msgid "Source file:" msgstr "Quelldatei:" msgid "Target file:" msgstr "Zieldatei:" msgid "Progress:" msgstr "Fortschritt:" msgid "*File info" msgstr "*Datei-Info" msgid "File info" msgstr "Datei-Info" msgid "There are unsaved changes to the file metadata." msgstr "Es existieren ungespeicherte Veränderungen an den Datei-Metadaten." msgid "Save and close" msgstr "Speichern und schließen" msgid "Discard changes" msgstr "Änderungen verwerfen" msgid "Do not close" msgstr "Nicht schließen" #, c-format msgid "" "Conversion error in field %s:\n" "'%s' does not conform to format '%s'!" msgstr "" "Umwandlungsfehler im Feld %s:\n" "'%s' stimmt nicht mit '%s' überein!" msgid "" "Attached Picture frame with no image set!\n" "Please set an image or remove the frame." msgstr "" "Angehängter Bilderrahmen enthält kein Bild!\n" "Bitte fügen Sie ein Bild ein oder entferne Sie den Rahmen." #, c-format msgid "" "Failed to write metadata to file.\n" "Reason: %s" msgstr "" "Das Schreiben von Metadaten schlug fehl.\n" "Grund: %s" #, c-format msgid "" "Error converting field %s to Year:\n" "'%s' is not an integer number!" msgstr "" "Fehler beim Umwandeln des Feldes %s zum Jahr:\n" "'%s' ist keine ganze Zahl!" msgid "Please specify the file to save the image to." msgstr "Bitte geben Sie die Datei an, in der das Bild gespeichert werden soll" msgid "(no image)" msgstr "(kein Bild)" msgid "(error loading image)" msgstr "(Fehler beim Laden des Bildes)" msgid "Please specify the file to load the image from." msgstr "Bitte geben Sie die Datei an, aus der das Bild geladen werden soll." #, c-format msgid "" "Could not load image from:\n" "%s" msgstr "" "Konnte Bild von folgender Stelle nicht laden:\n" "%s" #, c-format msgid "MIME type: %s" msgstr "MIME-Typ: %s" msgid "Picture type:" msgstr "Bildtyp:" msgid "Description:" msgstr "Beschreibung:" msgid "(no description)" msgstr "(Keine Beschreibung)" msgid "Change" msgstr "Ändern" msgid "Save" msgstr "Speichern" msgid "Import as Record" msgstr "Als Album importieren" msgid "Import as Track No." msgstr "Als Titelnummer importieren" msgid "Import as RVA" msgstr "Als RVA importieren" msgid "Add" msgstr "Hinzufügen" msgid "field:" msgstr "Feld:" msgid "tag:" msgstr "Tag:" msgid "Audio CD" msgstr "Audio-CD" msgid "Track:" msgstr "Titel:" msgid "File:" msgstr "Datei:" msgid "Audio data" msgstr "Audio-Daten" msgid "Format:" msgstr "Format:" msgid "Length:" msgstr "Länge:" msgid "Samplerate:" msgstr "Samplerate:" #, c-format msgid "%ld Hz" msgstr "%ld Hz" msgid "Channel count:" msgstr "Kanalanzahl:" msgid "MONO" msgstr "MONO" msgid "STEREO" msgstr "STEREO" msgid "Bandwidth:" msgstr "Bandbreite:" msgid "Total samples:" msgstr "Samples gesamt:" msgid "Mode:" msgstr "Modus:" msgid "Type:" msgstr "Typ:" msgid "Channels:" msgstr "Kanäle:" msgid "Patterns:" msgstr "Muster:" msgid "Samples:" msgstr "Samples:" msgid "Instruments:" msgstr "Instrumente:" msgid "Samples" msgstr "Samples" msgid "Instruments" msgstr "Instrumente" msgid "Name" msgstr "Name" msgid "STOPPING" msgstr "Wird GESTOPPT" msgid "Output:" msgstr "Ausgabe:" msgid "No output" msgstr "Keine Ausgabe" msgid "SRC Type: " msgstr "SRC-Typ: " #, c-format msgid "Loop range: %d-%d%% [%s - %s]" msgstr "Schleifenlänge: %d-%d%% [%s - %s]" #, c-format msgid "Loop range: %d-%d%%" msgstr "Schleifenlänge: %d-%d%%" msgid "" "One or more stores in Music Store have been modified.\n" "Do you want to save them before exiting?" msgstr "" "Eine oder mehrere Sammlungen in der Musiksammlung wurden verändert.\n" "Möchten Sie diese vor dem Beenden speichern?" msgid "Do not exit" msgstr "Nicht beenden" msgid "Quit" msgstr "Beenden" #, c-format msgid "Position: %d%%" msgstr "Position: %d%%" #, c-format msgid "Mute" msgstr "Stumm" #, c-format msgid "%d dB" msgstr "%d dB" #, c-format msgid "Volume: %s" msgstr "Lautstärke: %s" #, c-format msgid "%d%% R" msgstr "%d%% R" #, c-format msgid "%d%% L" msgstr "%d%% L" #, c-format msgid "C" msgstr "C" #, c-format msgid "Balance: %s" msgstr "Balance: %s" msgid "JACK connection lost" msgstr "JACK-Verbindung verloren" msgid "" "JACK has either been shutdown or it disconnected Aqualung because it was not " "fast enough. All you can do now is restart both JACK and Aqualung." msgstr "" "JACK wurde entweder beendet oder es hat Aqualung abgekoppelt weil Aqualung " "nicht schnell genug war. JACK und Aqualung sollten neu gestartet werden." msgid "Warn me if the Window Manager does not support system tray" msgstr "Warnen, falls der Fenstermanager keine Kontrollleiste unterstützt" msgid "" "Aqualung is compiled with system tray support, but the status icon could not " "be embedded in the notification area. Your desktop may not have support for " "a system tray, or it has not been configured correctly." msgstr "" "Aqualung wurde mit Kontrollleisten-Unterstützung kompiliert, aber das " "Statussymbol konnte nicht in die Kontrollleiste eingebettet werden. Ihre " "Benutzeroberfläche unterstützt möglicherweise keine Kontrollleiste oder sie " "wurde nicht richtig konfiguriert." msgid "Settings" msgstr "Einstellungen" msgid "Skin chooser" msgstr "Oberflächenauswahl" msgid "JACK port setup" msgstr "JACK-Verbindung einrichten" msgid "Previous song" msgstr "Vorheriger Titel" msgid "Stop" msgstr "Stop" msgid "Next song" msgstr "Nächster Titel" msgid "Play/Pause" msgstr "Wiedergabe/Pause" msgid "Play" msgstr "Wiedergabe" msgid "Pause" msgstr "Pause" msgid "Repeat current song" msgstr "Derzeitigen Titel wiederholen" msgid "Repeat all songs" msgstr "Alle Titel wiederholen" msgid "Shuffle songs" msgstr "Zufällige Wiedergabe" msgid "Toggle playlist" msgstr "Playliste ein-/ausblenden" msgid "Toggle music store" msgstr "Musiksammlung ein-/ausblenden" msgid "Toggle LADSPA patch builder" msgstr "LADSPA-Schaltkasten ein-/ausblenden" msgid "Show Aqualung" msgstr "Aqualung zeigen" msgid "Hide Aqualung" msgstr "Aqualung verbergen" msgid "Previous" msgstr "Vorheriger" msgid "Next" msgstr "Nächster" #, c-format msgid "%.1f MB / %.1f MB" msgstr "%.1f MB / %.1f MB" #, c-format msgid "%d / %d files" msgstr "%d / %d Dateien" #, c-format msgid "%d / %d directories" msgstr "%d / %d Ordner" msgid "Cannot write to selected directory. Please select another directory." msgstr "" "Kann im ausgewählten Ordner nicht schreiben. Bitte wählen Sie einen anderen." msgid "Done" msgstr "Fertig" msgid "Aborted..." msgstr "Abgebrochen …" msgid "Please enter directory name." msgstr "Bitte geben Sie einen Ordnernamen ein" msgid "Create directory" msgstr "Ordner anlegen" msgid "Please enter a new name." msgstr "Bitte geben Sie einen neuen Namen ein" msgid "Rename" msgstr "Umbenennen" #, c-format msgid "" "Directory '%s' will be removed with its entire contents.\n" "\n" "Do you want to proceed?" msgstr "" "Ordner '%s' wird mit seinem gesamten Inhalt entfernt.\n" "\n" "Möchten Sie fortfahren?" #, c-format msgid "" "File '%s' will be removed.\n" "\n" "Do you want to proceed?" msgstr "" "Datei '%s' wird entfernt.\n" "\n" "Möchten Sie fortfahren?" msgid "Remove" msgstr "Entfernen" #, c-format msgid " (%.1f MB)" msgstr " (%.1f MB)" #, c-format msgid " (capacity = %.1f MB)" msgstr " (Kapazität = %.1f MB)" #, c-format msgid " Free space (%.1f MB)" msgstr " Freier Speicherplatz (%.1f MB)" msgid "" "No suitable iRiver iFP device found.\n" "Perhaps it is unplugged or turned off." msgstr "" "Kein passendes iRiver-iFP-Gerät gefunden.\n" "Möglicherweise ist es ausgesteckt oder ausgeschalten." msgid "" "Device is busy.\n" "(Aqualung was unable to claim its interface.)" msgstr "" "Gerät ist beschäftigt.\n" "(Aqualung war es nicht möglich, das Gerät anzusprechen)" msgid "" "Device is not responding.\n" "Try jiggling the handle." msgstr "" "Gerät reagiert nicht.\n" "Bitte Überprüfen Sie den Anschluss des Gerätes." msgid "Please select a local path." msgstr "Bitte wählen Sie einen lokalen Pfad." msgid "Please select at least one valid song from playlist." msgstr "Bitte wählen Sie mindestens einen gültigen Titel aus der Playliste." #, c-format msgid "" "One song has format unsupported by your player.\n" "\n" "Do you want to proceed?" msgstr "" "Ein Titel hat ein Format, das von Aqualung nicht unterstützt wird.\n" "Möchten Sie fortfahren?" #, c-format msgid "" "%d of %d songs have format unsupported by your player.\n" "\n" "Do you want to proceed?" msgstr "" "%d von %d Titeln haben ein Format, das von Aqualung nicht unterstützt wird.\n" "\n" "Möchten Sie fortfahren?" #, c-format msgid "" "The selected song has format unsupported by your player.\n" "\n" "Do you want to proceed?" msgstr "" "Der ausgewählte Titel hat ein Format, das von Aqualung nicht unterstützt " "wird.\n" "Möchten Sie fortfahren?" #, c-format msgid "" "None of the selected songs has format supported by your player.\n" "\n" "Do you want to proceed?" msgstr "" "Keiner der ausgewählten Titel hat ein Format, das von Aqualung unterstützt " "wird.\n" "\n" "Möchten Sie fortfahren?" msgid "iFP device manager (upload mode)" msgstr "iFP-Geräteverwaltung (Hochlade-Modus)" msgid "iFP device manager (download mode)" msgstr "iFP-Geräteverwaltung (Herunterlade-Modus)" msgid "Selected files:" msgstr "Ausgewählte Dateien:" msgid "Songs info" msgstr "Titelinformationen" msgid "Model:" msgstr "Modell:" msgid "Battery" msgstr "Batterie" msgid "Free space" msgstr "Freier Speicherplatz" msgid "Device status" msgstr "Gerätestatus" msgid "Size" msgstr "Größe" msgid "Create a new directory" msgstr "Neuen Ordner anlegen" msgid "Remote directory" msgstr "Entfernt liegender Ordner" msgid "Local directory" msgstr "Lokaler Ordner" msgid "Browse" msgstr "Durchsuchen" msgid "File name: " msgstr "Dateiname:" msgid "Current file: " msgstr "Derzeitige Datei:" msgid "Overall: " msgstr "Insgesamt:" msgid "Idle" msgstr "Leerlauf" msgid "Transfer progress" msgstr "Übertragungsfortschritt" msgid "Close window when transfer complete" msgstr "Fenster nach vollständiger Übertragung schließen" msgid "_Upload" msgstr "_Hochladen" msgid "_Download" msgstr "_Herunterladen" msgid "_Abort" msgstr "_Abbrechen" msgid "Success" msgstr "Erfolgreich" msgid "Memory allocation error" msgstr "Speicherzuordnungsfehler" msgid "Unable to open file" msgstr "Außerstande Datei zu öffnen" msgid "No metadata support for this format" msgstr "Keine Metadatenunterstützung für dieses Format" msgid "File is not writable" msgstr "Datei ist nicht beschreibbar" msgid "Invalid 'Track no.' field value" msgstr "Ungültiger Wert im Feld »Titelnummer«" msgid "Invalid 'Genre' field value" msgstr "Ungültiger Wert im Feld »Genre«" msgid "Conversion to target charset failed" msgstr "Konvertierung zur Ziel-Charakterkodierung fehlgeschlagen" msgid "Internal error" msgstr "Interner Fehler" msgid "Unknown error" msgstr "Unbekannter Fehler" msgid "Album" msgstr "Album" msgid "Date" msgstr "Datum" msgid "Genre" msgstr "Genre" msgid "Track No." msgstr "Titelnummer" msgid "Comment" msgstr "Kommentar" msgid "Disc" msgstr "Medium" msgid "Performer" msgstr "Interpret" msgid "Description" msgstr "Beschreibung" msgid "Organization" msgstr "Organisation" msgid "Location" msgstr "Ort" msgid "Contact" msgstr "Kontakt" msgid "License" msgstr "Lizenz" msgid "Copyright" msgstr "Urheberrecht" msgid "ISRC" msgstr "ISRC" msgid "Version" msgstr "Version" msgid "Subtitle" msgstr "Untertitel" msgid "Debut Album" msgstr "Debutalbum" msgid "Publisher" msgstr "Herausgeber" msgid "Conductor" msgstr "Dirigent" msgid "Composer" msgstr "Komponist" msgid "Publication Right" msgstr "Veröffentlichungsrecht" msgid "File" msgstr "Datei" msgid "EAN/UPC" msgstr "EAN/UPC" msgid "ISBN" msgstr "ISBN" msgid "Catalog Number" msgstr "Katalognummer" msgid "Label Code" msgstr "Label-Code" msgid "Record Date" msgstr "Aufnahmedatum" msgid "Record Location" msgstr "Aufnahmeort/Studio" msgid "Media" msgstr "Medientyp" msgid "Index" msgstr "Index" msgid "Related" msgstr "Verwandt" msgid "Abstract" msgstr "Zusammenfassung" msgid "Language" msgstr "Sprache" msgid "Bibliography" msgstr "Bibliographie" msgid "Introplay" msgstr "Introplay" msgid "BPM" msgstr "BPM" msgid "Encoding Time" msgstr "Kodierungszeit" msgid "Playlist Delay" msgstr "Playlisten-Verzögerung" msgid "Original Release Time" msgstr "Veröffentlichungszeitpunkt des Originals" msgid "Release Time" msgstr "Veröffentlichungszeitpunkt" msgid "Tagging Time" msgstr "Tagging-Zeitpunkt" msgid "Encoded by" msgstr "Kodiert von" msgid "Lyricist/Text Writer" msgstr "Lyriker/Texter" msgid "File Type" msgstr "Dateityp" msgid "Involved People" msgstr "Beteiligte Personen" msgid "Content Group" msgstr "Inhaltsgruppe" msgid "Initial key" msgstr "Grundton" msgid "Musician Credits" msgstr "Mitwirkende Musiker" msgid "Mood" msgstr "Stimmung" msgid "Original Album" msgstr "Originalaufnahme" msgid "Original Filename" msgstr "Originaler Dateiname" msgid "Original Lyricist" msgstr "Originaltexter" msgid "Original Artist" msgstr "Originalinterpret" msgid "File Owner" msgstr "Dateieigentümer" msgid "Band/Orchestra" msgstr "Band/Orchester" msgid "Interpreted/Remixed" msgstr "Interpretiert/neu gemischt" msgid "Part Of A Set" msgstr "Teil der Serie" msgid "Produced" msgstr "Produziert" msgid "Internet Radio Station Name" msgstr "Name der Internetradiostation" msgid "Internet Radio Station Owner" msgstr "Besitzer der Internetradiostation" msgid "Album Sort Order" msgstr "Text für Albensortierung" msgid "Performer Sort Order" msgstr "Text für Interpretensortierung" msgid "Title Sort Order" msgstr "Text für Titelsortierung" msgid "Software" msgstr "Software" msgid "Set Subtitle" msgstr "Untertitel setzen" msgid "User Defined Text" msgstr "Benutzerdefinierter Text" msgid "Commercial Information" msgstr "Kommerzielle Information" msgid "Copyright/Legal Information" msgstr "Urheberrechtliche/Gesetzliche Information" msgid "Official Audio File Website" msgstr "Offizielle Audiodatei-Webseite" msgid "Official Artist Website" msgstr "Offizielle Webseite des Interpreten" msgid "Official Audio Source Website" msgstr "Offizielle Audioquellen-Webseite" msgid "Official Radio Station Website" msgstr "Offizielle Radiostations-Webseite" msgid "Payment" msgstr "Bezahlung" msgid "Publisher's Official Website" msgstr "Offizielle Herausgeber-Webseite" msgid "User Defined URL" msgstr "Benutzerdefinierte Adresse" msgid "Vendor" msgstr "Anbieter" msgid "ReplayGain Reference Loudness" msgstr "ReplayGain-Referenzlautstärke" msgid "ReplayGain Track Gain" msgstr "ReplayGain-Track-Gain" msgid "ReplayGain Track Peak" msgstr "ReplayGain-Track-Peak" msgid "ReplayGain Album Gain" msgstr "ReplayGain-Album-Gain" msgid "ReplayGain Album Peak" msgstr "ReplayGain-Album-Peak" msgid "Icy-Name" msgstr "Icy-Name" msgid "Icy-Description" msgstr "Icy-Beschreibung" msgid "Icy-Genre" msgstr "Icy-Genre" msgid "RVA" msgstr "RVA" msgid "Attached Picture" msgstr "Angefügtes Bild" msgid "Binary Object" msgstr "Binäres Objekt" msgid "NULL" msgstr "NULL" msgid "ID3v1" msgstr "ID3v1" msgid "ID3v2" msgstr "ID3v2" msgid "APE" msgstr "APE" msgid "Ogg Xiph Comments" msgstr "Ogg-Xiph-Kommentare" msgid "FLAC Pictures" msgstr "FLAC-Bilder" msgid "Musepack ReplayGain" msgstr "Musepack-ReplayGain" msgid "Generic StreamMeta" msgstr "Generic-StreamMeta" msgid "MPEG StreamMeta" msgstr "MPEG-StreamMeta" msgid "Module info" msgstr "Modul-Info" msgid "Unknown" msgstr "Unbekannt" msgid "Other" msgstr "Andere" msgid "File icon (32x32 PNG)" msgstr "Dateisymbol (32x32 PNG)" msgid "File icon (other)" msgstr "Dateisymbol (andere)" msgid "Front cover" msgstr "Cover-Vorderseite" msgid "Back cover" msgstr "Cover-Rückseite" msgid "Leaflet page" msgstr "Faltblatt" msgid "Album image" msgstr "Albumbild" msgid "Lead artist/performer" msgstr "Hauptinterpret" msgid "Artist/performer" msgstr "Interpret" msgid "Band/orchestra" msgstr "Band/Orchester" msgid "Lyricist/text writer" msgstr "Lyriker/Texter" msgid "Recording location/studio" msgstr "Aufnahmeort/Studio" msgid "During recording" msgstr "Während der Aufnahme" msgid "During performance" msgstr "Während der Aufführung" msgid "Movie/video screen capture" msgstr "Film/Video Aufzeichnung" msgid "A large, coloured fish" msgstr "Ein großer, farbiger Fisch" msgid "Illustration" msgstr "Illustration" msgid "Band/artist logotype" msgstr "Schriftzug Band/Interpret" msgid "Publisher/studio logotype" msgstr "Schriftzug Herausgeber/Studio" msgid "Music Store" msgstr "Musiksammlung" msgid "Search..." msgstr "Suchen …" msgid "Collapse all items" msgstr "Alle Elemente einklappen" msgid "Edit item..." msgstr "Element bearbeiten …" msgid "Add item..." msgstr "Element hinzufügen …" msgid "Remove item..." msgstr "Element entfernen …" msgid "Save all stores" msgstr "Alle Sammlungen speichern" msgid "Create empty store..." msgstr "Leere Sammlung anlegen …" msgid "*Music Store" msgstr "*Musiksammlung" #, c-format msgid "Do you want to save store \"%s\" before removing from Music Store?" msgstr "" "Möchten Sie die Sammlung \"%s\" speichern, bevor sie aus der Musiksammlung " "entfernt wird?" msgid "" "You will need to restart Aqualung for the following changes to take effect:" msgstr "" "Aqualung muss neu gestartet werden, damit die folgenden Veränderungen " "wirksam werden:" msgid "Select a font..." msgstr "Schriftart wählen …" msgid "Disable skin support" msgstr "Oberflächen-Unterstützung deaktivieren" msgid "rw" msgstr "rw" msgid "r" msgstr "r" msgid "unreachable" msgstr "nicht erreichbar" msgid "Please select a Programable Title Format File." msgstr "Bitte wählen Sie eine programmierbare Titelformatdatei." msgid "Please select a Music Store database." msgstr "Bitte wähle Sie eine Musiksammlungsdatenbank." msgid "Paths must either be absolute or starting with a tilde." msgstr "Pfade müssen absolut sein oder mit einer Tilde beginnen." msgid "The specified store has already been added to the list." msgstr "Die angegebene Sammlung wurde bereits zur Liste hinzugefügt." #, c-format msgid "" "\n" "The template string you enter here will be used to construct a single title " "line from an Artist, a Record and a Track name. These are denoted by %%%%a, %" "%%%r and %%%%t, respectively.\n" msgstr "" "\n" "Diese Zeichenketten-Maske wird für die Konstruktion einer Titelzeile aus " "einem Interpreten, einem Album und einem Titel benutzt. Diese werden mit %%%%" "a, %%%%r und %%%%t bezeichnet.\n" msgid "" "\n" "The file you enter/choose here will set the Lua program to use to format the " "title. See the Aqualung manual for details. Here is a quick example of what " "you can use in the file:\n" "\n" "function playlist_title()\n" " return m('artist') .. '-' .. m('title') .. ' (' .. m('album') .. ') (' .. i" "('filename') .. ')'\n" "end" msgstr "" "\n" "Die Datei, die Sie hier eingeben oder auswählen, wird von Lua verwendet, um " "den Titel zu formatieren. Weitere Details findet man im Aqualung-Handbuch. " "Hier ist ein kurzes Beispiel dafür, was in der Datei verwendet werden kann:\n" "\n" "function playlist_title()\n" " return m('artist') .. '-' .. m('title') .. ' (' .. m('album') .. ') (' .. i" "('filename') .. ')'\n" "end" msgid "" "\n" "The string you enter here will be parsed as a command line before parsing " "the actual command line parameters. What you enter here will act as a " "default setting and may or may not be overridden from the 'real' command " "line.\n" "\n" "Example: enter '-o alsa -R' below to use ALSA output running realtime as a " "default.\n" msgstr "" "\n" "Diese Zeichenkette wird als eine Befehlszeile geparst, bevor die " "eigentlichen Befehlszeilen-Parameter geparst werden. Was Sie hier schreiben " "wird als Voreinstellung fungieren und kann durch die »echte« Befehlszeile " "überschrieben werden.\n" "\n" "Beispiel: Eingabe von '-o alsa -R' um die ALSA-Ausgabe in Echtzeit als eine " "Voreinstellung zu benutzen.\n" msgid "" "Paths must either be absolute or starting with a tilde, which will be " "expanded to the user's home directory.\n" "\n" "Drag and drop entries in the list to set the store order in the Music Store." msgstr "" "Pfade müssen entweder absolut sein oder mit einer Tilde beginnen, welche zum " "persönlichen Ordner des Benutzers erweitert wird.\n" "\n" "Ziehen Sie die Einträge in der Liste, um die Reihenfolge der Sammlungen in " "der Musiksammlung zu verändern." msgid "" "\n" "Set the drive speed for CD playing in CD-ROM speed units. One speed unit " "equals to 176 kBps raw data reading speed. Warning: not all drives honor " "this setting.\n" "\n" "Lower speed usually means less drive noise. However, when using Paranoia " "error correction modes for increased accuracy, generally much larger speeds " "are required to prevent buffer underruns (and thus audible drop-outs).\n" "\n" "Please note that these settings do not apply to CD Ripping, which always " "happens with maximum available speed and with error correction modes " "manually set before every run." msgstr "" "\n" "Einstellung der Laufwerksgeschwindigkeit für das Abspielen von CDs in CD-ROM " "Geschwindigkeits-Einheiten. Eine Geschwindigkeitseinheit entspricht einer " "Rohdaten-Lesegeschwindigkeit von 176 kBps. Warnung: Nicht alle Laufwerke " "beachten diese Einstellung.\n" "\n" "Weniger Geschwindigkeit bedeutet üblicherweise weniger Laufwerkslärm. Wenn " "Sie jedoch den »Paranoia«-Fehlerkorrektur-Modus verwenden, werden " "üblicherweise höhere Geschwindigkeiten benötigt, um leere Puffer und damit " "hörbare Aussetzer zu vermeiden.\n" "\n" "Bitte nehmen Sie zur Kenntnis, dass diese Einstellungen nicht das Auslesen " "von CDs betreffen, welches immer bei maximaler Geschwindigkeit und händisch " "gesetzten Fehlerkorrekturmodi ausgeführt wird." msgid "" "\n" "Most drives let Aqualung know when a CD has been inserted or removed by " "providing a 'media changed' flag. However, some drives don't set this flag " "properly, and thus it may happen that a newly inserted CD remains unnoticed " "to Aqualung. In such cases, enabling this option should help." msgstr "" "\n" "Die meisten Laufwerke benachrichtigen Aqualung, wenn eine CD eingelegt oder " "ausgeworfen worden ist. Jedoch trifft das nicht auf alle Laufwerke zu, " "weshalb eine neu eingelegte CD möglicherweise nicht von Aqualung " "wahrgenommen wird. In solchen Fällen sollte das Aktivieren dieser Option " "Abhilfe schaffen." msgid "" "\n" "Here you should enter a comma-separated list of domains\n" "that should be accessed without using the proxy set above.\n" "Example: localhost, .localdomain, .my.domain.com" msgstr "" "\n" "Hier sollten Sie eine mit Komma getrennte Liste von\n" "Domänen eingeben, die ohne die Benutzung des oben eingestellten\n" "Proxy-Servers angesprochen werden sollen.\n" "Beispiele: localhost, .localdomain, .my.domain.com" msgid "Embed playlist into main window" msgstr "Playliste ins Hauptfenster einbetten" msgid "Enable systray" msgstr "Kontrollleistensymbol aktivieren" msgid "Do nothing" msgstr "Nichts unternehmen" msgid "Change volume" msgstr "Lautstärke regeln" msgid "Change balance" msgstr "Balance einstellen" msgid "Change song position" msgstr "Position im Titel ändern" msgid "Change current song" msgstr "Derzeitigen Titel ändern" msgid "Left button" msgstr "Linke Taste" msgid "Middle button" msgstr "Mittlere Taste" msgid "Right button" msgstr "Rechte Taste" msgid "Button" msgstr "Taste" msgid "Left and right mouse buttons are reserved." msgstr "Linke und rechte Maustaste sind reserviert." msgid "This button is already assigned." msgstr "Diese Taste ist bereits belegt." msgid "Add mouse button command" msgstr "Befehl zum Hinzufügen von Maustasten" msgid "Mouse button" msgstr "Maustaste" msgid "Click here to set mouse button" msgstr "Klicken Sie hier, um die Maustasten festzulegen" msgid "Command" msgstr "Befehl" msgid "Main window" msgstr "Hauptfenster" msgid "Disable control buttons relief" msgstr "Relief bei Kontrollknöpfen deaktivieren" msgid "Combine play and pause buttons" msgstr "Wiedergabe- und Pausenknopf vereinigen" msgid "Keep main window always on top" msgstr "Hauptfenster immer im Vordergrund behalten" msgid "Show song name in the main window's title" msgstr "Titelnamen im Titel des Hauptfensters zeigen" msgid "Title Format" msgstr "Titelformat" msgid "Programmable title format file" msgstr "Programmierbare Titelformatdatei" msgid "Systray" msgstr "Kontrollleiste" msgid "Start minimized" msgstr "Minimiert starten" msgid "Play/Stop song" msgstr "Titel wiedergeben/stoppen" msgid "Play/Pause song" msgstr "Titel wiedergeben/pausieren" msgid "Mouse wheel" msgstr "Mausrad" msgid "Vertical mouse wheel:" msgstr "Vertikales Mausrad:" msgid "Horizontal mouse wheel:" msgstr "Horizontales Mausrad:" msgid "Mouse buttons" msgstr "Maustasten" msgid "Miscellaneous" msgstr "Sonstiges" msgid "Implicit command line" msgstr "Implizite Befehlszeile" msgid "Cover art" msgstr "Covers" msgid "Default cover width:" msgstr "Standard-Coverbreite:" msgid "50 pixels" msgstr "50 Pixel" msgid "100 pixels" msgstr "100 Pixel" msgid "200 pixels" msgstr "200 Pixel" msgid "300 pixels" msgstr "300 Pixel" msgid "use browser window width" msgstr "Auswahlfensterbreite benutzen" msgid "Do not magnify images with smaller width" msgstr "Bilder mit geringerer Breite nicht vergrößern" msgid "Show cover thumbnail for Music Store tracks only" msgstr "Miniatur-Coverbild nur für Titel aus der Musiksammlung zeigen" msgid "Don't show cover thumbnail in the main window" msgstr "Miniatur-Coverbild nicht im Hauptfenster anzeigen" msgid "Enable tooltips" msgstr "Minihilfen einschalten" msgid "Simple view in LADSPA patch builder" msgstr "Einfache Ansicht beim LADSPA-Schaltkasten" msgid "United windows minimization" msgstr "Fenster gemeinsam minimieren" msgid "Show hidden files and directories in file choosers" msgstr "Versteckte Dateien und Ordner in der Dateiauswahl anzeigen" msgid "Show tags tab first in the file info dialog" msgstr "Tag-Reiter als ersten im Dateiinformationsdialog anzeigen" msgid "Playlist" msgstr "Playliste" msgid "Put control buttons at the bottom of playlist" msgstr "Kontrollknöpfe unten an der Playliste platzieren" msgid "Save and restore the playlist on exit/startup" msgstr "Playliste beim Beenden/Starten speichern und laden" msgid "Save playlist periodically [min]:" msgstr "Playliste in periodischen Zeitabständen speichern [min]:" msgid "Album mode is the default when adding entire records" msgstr "Album-Modus ist die Vorgabe, wenn ein gesamtes Album hinzugefügt wird" msgid "Always show the tab bar" msgstr "Reiterleiste immer anzeigen" msgid "Show close button in tab" msgstr "Schließknopf im Reiter anzeigen" msgid "When shuffling, records added in Album mode are played in order" msgstr "" "Alben, die im Album-Modus hinzugefügt wurden, im Zufallsmodus geordnet " "wiedergeben" msgid "Enable statusbar" msgstr "Statusleiste aktivieren" msgid "Enable statusbar in playlist" msgstr "Statusleiste in der Playliste aktivieren" msgid "Show soundfile size in statusbar" msgstr "Größe der Datei in der Statusleiste anzeigen" msgid "Show RVA values" msgstr "RVA-Werte anzeigen" msgid "Show track lengths" msgstr "Titellängen anzeigen" msgid "Show active track name in bold" msgstr "Namen des aktiven Titels fett anzeigen" msgid "Automatically roll to active track" msgstr "Automatisch zum aktiven Titel rollen" msgid "Enable rules hint" msgstr "Regelhinweise anzeigen" msgid "Playlist column order" msgstr "Reihenfolge der Spalten in der Playliste" msgid "" "Drag and drop entries in the list below \n" "to set the column order in the Playlist." msgstr "" "Ziehen Sie die Einträge in der nachstehenden Liste,\n" "um die Reihenfolge der Spalten in der Playliste zu ändern." msgid "Column" msgstr "Spalte" msgid "Track titles" msgstr "Titel" msgid "RVA values" msgstr "RVA-Werte" msgid "Track lengths" msgstr "Titellängen" msgid "Hide comment pane" msgstr "Kommentarausschnitt verbergen" msgid "Hide the Music Store comment pane" msgstr "Musiksammlungs-Kommentarausschnitt verbergen" msgid "Enable toolbar" msgstr "Werkzeugleiste aktivieren" msgid "Enable toolbar in Music Store" msgstr "Werkzeugleiste in der Musiksammlung aktivieren" msgid "Enable statusbar in Music Store" msgstr "Statusleiste in der Musiksammlung aktivieren" msgid "Expand Stores on startup" msgstr "Sammlungen beim Start ausklappen" msgid "Enable tree node icons" msgstr "Baumknoten-Symbole aktivieren" msgid "Enable Music Store tree node icons" msgstr "Baumknoten-Symbole in der Musiksammlung aktivieren" msgid "Ask for confirmation when removing items" msgstr "Frage nach Bestätigung beim Entfernen von Elementen" msgid "Paths to Music Store databases" msgstr "Pfade zu den Musiksammlungsdatenbanken" msgid "Path" msgstr "Pfad" msgid "Access" msgstr "Zugriff" msgid "Refresh" msgstr "Aktualisieren" msgid "DSP" msgstr "DSP" msgid "LADSPA plugin processing" msgstr "LADSPA-Plugin-Verarbeitung" msgid "Pre Fader (before Volume & Balance)" msgstr "Pre-Fader (vor Lautstärke & Balance)" msgid "Post Fader (after Volume & Balance)" msgstr "Post-Fader (nach Lautstärke & Balance)" msgid "" "Aqualung is compiled without LADSPA plugin support.\n" "See the About box and the documentation for details." msgstr "" "Aqualung wurde ohne LADSPA-Plugin-Unterstützung kompiliert.\n" "Details findet man in der »Über Aqualung«-Box und in der Dokumentation." msgid "Sample Rate Converter type" msgstr "Samplerate-Konvertertyp" msgid "" "Aqualung is compiled without Sample Rate Converter support.\n" "See the About box and the documentation for details." msgstr "" "Aqualung wurde ohne Samplerate-Konverterunterstützung kompiliert.\n" "Details findet man in der »Über Aqualung«-Box und in der Dokumentation." msgid "Playback RVA" msgstr "Wiedergabe-RVA" msgid "Enable playback RVA" msgstr "Aktiviere Wiedergabe-RVA" msgid "Listening environment:" msgstr "Hörumgebung:" msgid "Audiophile" msgstr "Audiophil" msgid "Living room" msgstr "Wohnzimmer" msgid "Office" msgstr "Büro" msgid "Noisy workshop" msgstr "Laute Werkstatt" msgid "Reference volume [dBFS] :" msgstr "Referenzlautstärke [dBFS] :" msgid "Steepness [dB/dB] :" msgstr "Steilheit [dB/dB] :" msgid "RVA for Unmeasured Files [dB] :" msgstr "RVA für ungemessene Dateien [dB] :" msgid "Apply averaged RVA to tracks of the same record" msgstr "Durchschnittliches RVA auf alle Titel eines Albums anwenden" msgid "Drop statistical aberrations based on" msgstr "Verringerung der statistischen Abweichung basierend auf" #, no-c-format msgid "% of standard deviation" msgstr "% der Standardabweichung" msgid "Linear threshold [dB]" msgstr "Linearschwelle [dB]" msgid "Linear threshold [dB] :" msgstr "Linearschwelle [dB] :" #, no-c-format msgid "% of standard deviation :" msgstr "% der Standardabweichung :" msgid "ReplayGain tag to use (with fallback to the other): " msgstr "Folgendes ReplayGain-Tag benutzen (mit Rückfall zum anderen): " msgid "Replaygain_track_gain" msgstr "Replaygain_track_gain" msgid "Replaygain_album_gain" msgstr "Replaygain_album_gain" msgid "Adding files to Playlist" msgstr "Dateien werden zur Playliste hinzugefügt" msgid "" "Use basename only instead of full path\n" "if no metadata is available." msgstr "" "Basisnamen nur anstelle des gesamten Pfades benutzen,\n" "wenn keine Metadaten verfügbar sind." msgid "Metadata editor (File info dialog)" msgstr "Metadaten-Editor (Dateiinformationsdialog)" msgid "" "When adding new frames, try to set their contents\n" "from another tag's equivalent frame." msgstr "" "Wenn neue Frames hinzugefügt werden, versuchen ihre Inhalte\n" "aus dem äquivalenten Frame eines anderen Tags zu setzen." msgid "Batch update & encode (mass tagger, CD ripper, file export)" msgstr "" "Stapelweise aktualisieren und kodieren (Mass-Tagger, CD-Ausleser, " "Dateiexport)" msgid "Tags to add when creating or updating MPEG audio files:" msgstr "" "Tags, die beim Erstellen oder Aktualisieren von MPEG-Audiodateien " "hinzugefügt werden sollen:" msgid "" "Note: pre-existing tags will be updated even though they\n" "might not be checked here." msgstr "" "Hinweis: Bereits existierende Tags werden aktualisiert, auch wenn sie hier " "nicht ausgewählt sind." msgid "CD Audio" msgstr "CD-Audio" msgid "CD drive speed:" msgstr "CD-Laufwerksgeschwindigkeit" msgid "\tMaximum number of retries:" msgstr "\tMaximale Anzahl der Wiederholungen:" msgid "Force TOC re-read on every drive scan" msgstr "Nochmaliges TOC-Lesen bei jeder Laufwerksabfrage erzwingen" msgid "Automatically add CDs to Playlist" msgstr "CDs automatisch zur Playliste hinzufügen" msgid "Automatically remove CDs from Playlist" msgstr "CDs automatisch von der Playliste entfernen" msgid "CDDB server:" msgstr "CDDB-Server:" msgid "Connection timeout [sec]:" msgstr "Verbindungs-Zeitüberschreitung [Sek.]:" msgid "Email address for submission:" msgstr "E-Mail-Adresse für die Übertragung:" msgid "Local CDDB directory:" msgstr "Lokales CDDB-Verzeichnis:" msgid "Use the local database only" msgstr "Nur die lokale Datenbank benutzen" msgid "Protocol for querying (direct connection only):" msgstr "Protokoll für die Abfrage (nur bei direkter Verbindung):" msgid "CDDBP (port 888)" msgstr "CDDBP (Port 888)" msgid "HTTP (port 80)" msgstr "HTTP (Port 80)" msgid "Internet" msgstr "Internet" msgid "Direct connection to the Internet" msgstr "Direkte Verbindung zum Internet" msgid "Connect via HTTP proxy" msgstr "Verbinde über HTTP-Proxy" msgid "Proxy settings" msgstr "Proxy-Einstellungen" msgid "Proxy host:" msgstr "Proxy-Rechner:" msgid "Port:" msgstr "Port:" msgid "No proxy for:" msgstr "Kein Proxy für:" msgid "Timeout for socket I/O:" msgstr "Zeitüberschreitung für Sockel I/O:" msgid "seconds" msgstr "Sekunden" msgid "Appearance" msgstr "Aussehen" msgid "Override skin settings" msgstr "Oberflächen-Einstellungen überschreiben" msgid "Fonts" msgstr "Schriftarten" msgid "Playlist: " msgstr "Playliste: " msgid "Music Store: " msgstr "Musiksammlung: " msgid "Big timer: " msgstr "Große Zeitanzeige: " msgid "Small timers: " msgstr "Kleine Zeitanzeigen: " msgid "Song title: " msgstr "Titel: " msgid "Song info: " msgstr "Titelinformation: " msgid "Statusbar: " msgstr "Statusleiste: " msgid "Colors" msgstr "Farben" msgid "Song in playlist: " msgstr "Titel in der Playliste: " msgid "Active song in playlist: " msgstr "Aktiver Titel in der Playliste: " msgid "Error in title format string" msgstr "Fehler in der Titelformat-Zeichenkette" msgid "(Untitled)" msgstr "(Unbetitelt)" #, c-format msgid " (%d/%d)" msgstr " (%d/%d)" msgid "Select files" msgstr "Dateien wählen" msgid "Select directory" msgstr "Ordner wählen" msgid "Add URL" msgstr "Adresse hinzufügen" msgid "URL:" msgstr "Adresse:" msgid "Please specify the file to save the playlist to." msgstr "" "Bitte geben Sie die Datei an, in die die Playliste gespeichert werden soll." msgid "Please specify the file to load the playlist from." msgstr "" "Bitte geben Sie die Datei an, aus der die Playliste geladen werden soll." msgid "" "Playback RVA is currently disabled.\n" "Do you want to enable it now?" msgstr "" "Wiedergabe-RVA ist derzeit deaktiviert.\n" "Möchten Sie es jetzt aktivieren?" msgid "counting..." msgstr "zähle …" msgid "track" msgstr "Titel" msgid "tracks" msgstr "Titel" msgid "Rename playlist" msgstr "Playliste umbenennen" msgid "Name:" msgstr "Name:" msgid "New tab" msgstr "Neuer Reiter" msgid "Close tab" msgstr "Reiter schließen" msgid "Undo close tab" msgstr "Reiter schließen rückgängig machen" msgid "Close other tabs" msgstr "Alle anderen Reiter schließen" msgid " Selected: " msgstr " Ausgewählt: " msgid "Total: " msgstr "Gesamt: " msgid "Add files" msgstr "Dateien hinzufügen" msgid "" "Add files to playlist\n" "(Press right mouse button for menu)" msgstr "" "Dateien zur Playliste hinzufügen\n" "(Drücken Sie die rechte Maustaste für das Menü)" msgid "Select all" msgstr "Alles auswählen" msgid "" "Select all songs in playlist\n" "(Press right mouse button for menu)" msgstr "" "Alle Titel in der Playliste auswählen\n" "(Drücken Sie die rechte Maustaste für das Menü)" msgid "Remove selected" msgstr "Auswahl entfernen" msgid "" "Remove selected songs from playlist\n" "(Press right mouse button for menu)" msgstr "" "Markierte Titel von der Playliste entfernen\n" "(Drücken Sie die rechte Maustaste für das Menü)" msgid "Add directory" msgstr "Ordner hinzufügen" msgid "Select none" msgstr "Nichts auswählen" msgid "Invert selection" msgstr "Auswahl umkehren" msgid "Remove all" msgstr "Alle entfernen" msgid "Remove dead" msgstr "Tote Einträge entfernen" # Ausgewählte Titel bleiben in der Wiedergabeliste, alles anderen werden entfernt. msgid "Cut selected" msgstr "Ausgewählte freistellen" msgid "Save playlist" msgstr "Playliste speichern" msgid "Save all playlists" msgstr "Alle Playlisten speichern" msgid "Load playlist in new tab" msgstr "Playliste in neuem Reiter laden" msgid "Load playlist" msgstr "Playliste laden" msgid "Enqueue playlist" msgstr "Playliste einreihen" msgid "Send to iFP device" msgstr "An iFP-Gerät senden" msgid "Calculate RVA" msgstr "RVA messen" msgid "Separate" msgstr "Einzeln" msgid "Average" msgstr "Durchschnitt" msgid "Reread file metadata" msgstr "Datei-Metadaten erneut einlesen" msgid "File info..." msgstr "Datei-Info …" msgid "Roll to active song" msgstr "Zum derzeitigen Titel rollen" msgid "Stop adding files" msgstr "Hinzufügen von Dateien stoppen" msgid "Files selected for removal" msgstr "Zum Entfernen ausgewählte Dateien" msgid "Remove files" msgstr "Dateien entfernen" msgid "" "The selected files will be deleted from the filesystem. No recovery will be " "possible after this operation.\n" "\n" "Do you want to proceed?" msgstr "" "Die ausgewählten Dateien werden aus dem Dateisystem entfernt. " "Wiederherstellen wird nach dieser Operation nicht möglich sein.\n" "\n" "Möchten Sie fortfahren?" #, c-format msgid "Unable to remove %d file." msgstr "Außerstande %d Datei zu entfernen." #, c-format msgid "Unable to remove %d files." msgstr "Außerstande %d Dateien zu entfernen." msgid "LADSPA patch builder" msgstr "LADSPA-Schaltkasten" msgid "Available plugins" msgstr "Verfügbare Plugins" msgid "ID" msgstr "ID" msgid "Category" msgstr "Kategorie" msgid "Inputs" msgstr "Eingänge" msgid "Outputs" msgstr "Ausgänge" msgid "Running plugins" msgstr "Laufende Plugins" msgid "_Configure" msgstr "_Konfigurieren" msgid "Enable all plugins" msgstr "Alle Plugins aktivieren" msgid "Disable all plugins" msgstr "Alle Plugins deaktivieren" msgid "Invert current state" msgstr "Derzeitigen Zustand umkehren" msgid "Clear list" msgstr "Liste löschen" msgid "Untitled" msgstr "Unbenannt" msgid "JACK Port Setup" msgstr "JACK-Verbindung einrichten" msgid "Rescan" msgstr "Erneut abfragen" msgid "Available connections" msgstr "Verfügbare Verbindungen" msgid "Clear connections" msgstr "Verbindungen aufheben" msgid " out L" msgstr " Ausgang L" msgid " out R" msgstr " Ausgang R" msgid "Search the Music Store" msgstr "Musiksammlung durchsuchen" msgid "Key: " msgstr "Schlüssel: " msgid "Case sensitive" msgstr "Groß-/Kleinschreibung unterscheiden" msgid "Exact matches only" msgstr "Nur genaue Treffer" msgid "Select first and close window" msgstr "Wähle ersten Treffer und schließe Fenster" msgid "Search in:" msgstr "Suchen in:" msgid "Artist names" msgstr "Namen des Interpreten" msgid "Record titles" msgstr "Albentitel" msgid "Comments" msgstr "Kommentare" msgid "Search" msgstr "Suchen" msgid "Search the Playlist" msgstr "Playliste durchsuchen" msgid "Available skins" msgstr "Verfügbare Oberflächen" msgid "Drive info" msgstr "Laufwerks-Info" msgid "Device path:" msgstr "Gerätepfad:" msgid "Vendor:" msgstr "Anbieter:" msgid "Revision:" msgstr "Revision:" msgid "" "The information below is reported by the drive, and\n" "may not reflect the actual capabilities of the device." msgstr "" "Die nachfolgenden Informationen wurden vom Gerät geliefert\n" "und entsprechen möglicherweise nicht seinen tatsächlichen Fähigkeiten." msgid "Eject" msgstr "Auswerfen" msgid "Close tray" msgstr "Lade schließen" msgid "Disable manual eject" msgstr "Manuelles Auswerfen deaktivieren" msgid "Select juke-box disc" msgstr "Musikbox-CD wählen" msgid "Set drive speed" msgstr "Laufwerksgeschwindigkeit setzen" msgid "Detect media change" msgstr "Datenträgerwechsel erkennen" msgid "Read multiple sessions" msgstr "Mehrere Sitzungen lesen" msgid "Hard reset device" msgstr "Gerät hart zurücksetzen" msgid "Reading" msgstr "Lesen" msgid "Play CD Audio" msgstr "Audio-CD abspielen" msgid "Read CD-DA" msgstr "CD-DA lesen" msgid "Read CD+G" msgstr "CD+G lesen" msgid "Read CD-R" msgstr "CD-R lesen" msgid "Read CD-RW" msgstr "CD-RW lesen" msgid "Read DVD-R" msgstr "DVD-R lesen" msgid "Read DVD+R" msgstr "DVD+R lesen" msgid "Read DVD-RW" msgstr "DVD-RW lesen" msgid "Read DVD+RW" msgstr "DVD+RW lesen" msgid "Read DVD-RAM" msgstr "DVD-RAM lesen" msgid "Read DVD-ROM" msgstr "DVD-ROM lesen" msgid "C2 Error Correction" msgstr "C2 Fehlerkorrektur" msgid "Read Mode 2 Form 1" msgstr "Lesemodus 2 Form 1" msgid "Read Mode 2 Form 2" msgstr "Lesemodus 2 Form 2" msgid "Read MCN" msgstr "MCN lesen" msgid "Read ISRC" msgstr "ISRC lesen" msgid "Writing" msgstr "Schreiben" msgid "Write CD-R" msgstr "CD-R schreiben" msgid "Write CD-RW" msgstr "CD-RW schreiben" msgid "Write DVD-R" msgstr "DVD-R schreiben" msgid "Write DVD+R" msgstr "DVD-R schreiben" msgid "Write DVD-RW" msgstr "DVD-RW schreiben" msgid "Write DVD+RW" msgstr "DVD+RW schreiben" msgid "Write DVD-RAM" msgstr "DVD-RAM schreiben" msgid "Mount Rainier" msgstr "Mount-Rainier" msgid "Burn Proof" msgstr "Burn-Proof" msgid "Disc info" msgstr "CD-Info" msgid "This CD does not contain CD-Text information." msgstr "Diese CD beinhaltet keine CD-Text Information." msgid "drive" msgstr "Laufwerk" msgid "drives" msgstr "Laufwerke" msgid "record" msgstr "Album" msgid "records" msgstr "Alben" msgid "Add to playlist" msgstr "Zur Playliste hinzufügen" msgid "Add to playlist (Album mode)" msgstr "Zur Playliste hinzufügen (Album-Modus)" msgid "CDDB query for this CD..." msgstr "CDDB-Abfrage für diese CD …" msgid "Submit CD to CDDB database..." msgstr "CD zur CDDB-Datenbank übertragen …" msgid "Rip CD..." msgstr "CD auslesen …" msgid "Disc info..." msgstr "CD-Info …" msgid "Drive info..." msgstr "Laufwerks-Info …" msgid "Comments:" msgstr "Kommentare:" msgid "Please select the xml file for this store." msgstr "Bitte wählen Sie die xml-Datei für diese Sammlung aus." msgid "Create empty store" msgstr "Leere Sammlung erzeugen" msgid "Visible name:" msgstr "Angezeigter Name:" msgid "Edit Store" msgstr "Sammlung bearbeiten" msgid "Use relative paths in store file" msgstr "Relative Pfade in der Musiksammlungsdatei benutzen" msgid "Add Artist" msgstr "Interpreten hinzufügen" msgid "Name to sort by:" msgstr "Nach folgendem Namen sortieren:" msgid "Edit Artist" msgstr "Interpret bearbeiten" msgid "Please select the audio files for this record." msgstr "Bitte wählen Sie die Audiodateien für dieses Album aus." msgid "Add Record" msgstr "Album hinzufügen" msgid "Auto-create tracks from these files:" msgstr "Titel automatisch aus diesen Dateien erstellen:" msgid "_Add files..." msgstr "_Dateien hinzufügen …" msgid "Edit Record" msgstr "Album bearbeiten" msgid "Please select the audio file for this track." msgstr "Bitte wählen Sie die Audio Datei für dieses Lied aus." msgid "Add Track" msgstr "Titel hinzufügen" msgid "Edit Track" msgstr "Titel bearbeiten" msgid "Duration:" msgstr "Zeitdauer:" #, c-format msgid "Unmeasured" msgstr "Ungemessen" msgid "Volume level:" msgstr "Lautstärke:" msgid "Use manual RVA value [dB]" msgstr "Manuelles RVA-Level benutzen [dB]" #, c-format msgid "Really remove \"%s\" from the Music Store?" msgstr "Wirklich \"%s\" aus der Musiksammlung entfernen?" msgid "Stop adding songs" msgstr "Hinzufügen von Titeln stoppen" #, c-format msgid "" "The store '%s' already exists.\n" "Add it on the Settings/Music Store tab." msgstr "" "Die Sammlung '%s' existiert bereits.\n" "Fügen Sie sie am Reiter Einstellungen/Musiksammlung hinzu." #, c-format msgid "Really remove store \"%s\" from the Music Store?" msgstr "Sammlung \"%s\" wirklich aus der Musiksammlung entfernen?" msgid "Remove Store" msgstr "Sammlung entfernen" msgid "Do you want to save the store before removing?" msgstr "Möchten Sie die Sammlung vor dem Entfernen speichern?" msgid "Remove Artist" msgstr "Interpret entfernen" msgid "Remove Record" msgstr "Album entfernen" msgid "Remove Track" msgstr "Titel entfernen" msgid "Update file metadata" msgstr "Datei-Metadaten aktualisieren" msgid "Track name" msgstr "Titelname" msgid "Track comment" msgstr "Titelkommentar" msgid "Track number" msgstr "Titelnummer" msgid "Failed to set metadata for the following files:" msgstr "Das Schreiben von Metadaten schlug bei folgenden Dateien fehl:" msgid "Filename" msgstr "Dateiname" msgid "Reason" msgstr "Grund" msgid "(no comment)" msgstr "(kein Kommentar)" msgid "artist" msgstr "Interpret" msgid "artists" msgstr "Interpreten" #, c-format msgid "" "File \"%s\" does not exist or your write permission has been withdrawn. " "Check if the partition containing the store file has been unmounted." msgstr "" "Datei »%s« nicht vorhanden oder Sie haben keine Schreibberechtigung. Prüfen " "Sie, ob die Partition mit der Musiksammlungsdatei ausgehängt worden ist." msgid "Build / Update store from filesystem..." msgstr "Erstellen / Aktualisieren der Sammlung vom Dateisystem …" msgid "Edit store..." msgstr "Sammlung bearbeiten …" msgid "Export store..." msgstr "Sammlung exportieren …" msgid "Save store" msgstr "Sammlung speichern" msgid "Remove store" msgstr "Sammlung entfernen" msgid "Add new artist to this store..." msgstr "Neuen Interpreten zu dieser Sammlung hinzufügen …" msgid "Calculate volume (recursive)" msgstr "Lautstärke messen (rekursiv)" msgid "Unmeasured tracks only" msgstr "Nur ungemessene Titel" msgid "All tracks" msgstr "Alle Titel" msgid "Batch-update file metadata..." msgstr "Datei-Metadaten stapelweise aktualisieren …" msgid "Add new artist..." msgstr "Neuen Interpreten hinzufügen …" msgid "Edit artist..." msgstr "Interpreten bearbeiten …" msgid "Export artist..." msgstr "Interpreten exportieren …" msgid "Remove artist" msgstr "Interpreten entfernen" msgid "Add new record to this artist..." msgstr "Neues Album zu diesem Interpreten hinzufügen …" msgid "Add new record..." msgstr "Neues Album hinzufügen …" msgid "Edit record..." msgstr "Album bearbeiten …" msgid "Export record..." msgstr "Album exportieren …" msgid "Remove record" msgstr "Album entfernen" msgid "Add new track to this record..." msgstr "Neuen Titel zu diesem Album hinzufügen …" msgid "CDDB query for this record..." msgstr "CDDB-Abfrage für dieses Album …" msgid "Submit record to CDDB database..." msgstr "Album zur CDDB-Datenbank übertragen …" msgid "Add new track..." msgstr "Neuen Titel hinzufügen …" msgid "Edit track..." msgstr "Titel bearbeiten …" msgid "Export track..." msgstr "Titel exportieren …" msgid "Remove track" msgstr "Titel entfernen" msgid "Calculate volume" msgstr "Lautstärke messen" msgid "Only if unmeasured" msgstr "Nur wenn ungemessen" msgid "In any case" msgstr "In jedem Fall" msgid "Update file metadata..." msgstr "Datei-Metadaten aktualisieren …" msgid "Please select the download directory for this podcast." msgstr "Bitte wählen Sie einen Ordner zum Speichern dieses Podcasts aus." msgid "Subscribe to new feed" msgstr "Neuen Feed abonnieren" msgid "Edit feed settings" msgstr "Feed-Einstellungen bearbeiten" msgid "Podcast URL:" msgstr "Podcast-Adresse:" msgid "Download directory:" msgstr "Ordner zum Herunterladen:" msgid "Auto-check interval [hour]:" msgstr "Automatisches Abfrageintervall [Stunden]:" msgid "" "Automatic update has been disabled for all feeds\n" "in the Podcasts store popup menu." msgstr "" "Automatische Aktualisierung wurde für alle Feeds\n" "im Musiksammlungs-Podcast-Menü deaktiviert." msgid "Limits" msgstr "Begrenzungen" msgid "Maximum number of items:" msgstr "Maximale Anzahl an Elementen:" msgid "Remove older items [day]:" msgstr "Entferne ältere Elemente [Tage]:" msgid "Maximum space to use [MB]:" msgstr "Maximaler Platzverbrauch [MB]:" msgid "Podcasts" msgstr "Podcasts" msgid "Updating..." msgstr "Aktualisiere …" msgid "Delete downloaded items from the filesystem" msgstr "Heruntergeladene Elemente aus dem Dateisystem löschen" msgid "Remove feed" msgstr "Feed entfernen" #, c-format msgid "Really remove '%s' from the Music Store?" msgstr "Wirklich '%s' aus der Musiksammlung entfernen?" msgid "Reorder feeds" msgstr "Feeds neu ordnen" msgid "" "Drag and drop entries in the list\n" "to set the feed order in the Music Store." msgstr "" "Ziehen Sie die Einträge in der Liste,\n" "um die Reihenfolge der Feeds in der Musiksammlung zu ändern." #, c-format msgid "Downloading %d/%d (%d%%) ..." msgstr "Herunterladen %d/%d (%d%%) …" msgid "item" msgstr "Element" msgid "items" msgstr "Elemente" msgid "new item" msgstr "Neues Element" msgid "new items" msgstr "Neue Elemente" msgid "feed" msgstr "Feed" msgid "feeds" msgstr "Feeds" msgid "Export item..." msgstr "Element exportieren …" msgid "Add all items to playlist" msgstr "Alle Elemente zur Playliste hinzufügen" msgid "Add all items to playlist (Album mode)" msgstr "Alle Elemente zur Playliste hinzufügen (Album-Modus)" msgid "Add new items to playlist" msgstr "Neue Elemente zur Playliste hinzufügen" msgid "Add new items to playlist (Album mode)" msgstr "Neue Elemente zur Playliste hinzufügen (Album-Modus)" msgid "Edit feed" msgstr "Feed bearbeiten" msgid "Export all items..." msgstr "Alle Elemente exportieren …" msgid "Export new items..." msgstr "Neue Elemente exportieren …" msgid "Update feed" msgstr "Feed aktualisieren" msgid "Abort ongoing update" msgstr "Laufende Aktualisierung abbrechen" msgid "Update all feeds" msgstr "Alle Feeds aktualisieren" msgid "Automatically update feeds" msgstr "Feeds automatisch aktualisieren" msgid "Unexpected end of string after '?'." msgstr "Unerwartetes Ende der Zeichenkette nach '?'." msgid "Expected '}' after '{', but end of string found." msgstr "" "Es wurde '}' nach '{' erwartet, aber das Ende der Zeichenkette gefunden." #, c-format msgid "Unknown conversion type character found after '%%%%'." msgstr "Unbekanntes Konvertierungstyp-Zeichen gefunden nach '%%%%'." msgid "Unknown conversion type character found after '?'." msgstr "Unbekanntes Konvertierungstyp-Zeichen gefunden nach '?'." msgid "day" msgstr "Tag" msgid "days" msgstr "Tage" msgid "All Files" msgstr "Alle Dateien" msgid "Extended Title Format Files (*.lua)" msgstr "Erweiterte Titelformatdateien (*.lua)" msgid "Music Store Files (*.xml)" msgstr "Musiksammlungsdateien (*.xml)" msgid "Aqualung playlist (*.xml)" msgstr "Aqualung-Playliste (*.xml)" msgid "MP3 Playlist (*.m3u)" msgstr "MP3-Playliste (*.m3u)" msgid "Multimedia Playlist (*.pls)" msgstr "Multimedia-Playliste (*.pls)" msgid "All Playlist Files" msgstr "Alle Playlisten-Dateien" msgid "All Audio Files" msgstr "Alle Audiodateien" msgid "Sound Files (*.wav, *.aiff, *.au, ...)" msgstr "Audiodateien (*.wav, *.aiff, *.au, …)" msgid "Free Lossless Audio Codec (*.flac)" msgstr "Free Lossless Audio Codec (*.flac)" msgid "MPEG Audio (*.mp3, *.mpa, *.mpega, ...)" msgstr "MPEG Audio (*.mp3, *.mpa, *.mpega, …)" msgid "Ogg Vorbis (*.ogg)" msgstr "Ogg Vorbis (*.ogg)" msgid "Ogg Speex (*.spx)" msgstr "Ogg Speex (*.spx)" msgid "Musepack (*.mpc)" msgstr "Musepack (*.mpc)" msgid "Monkey's Audio Codec (*.ape)" msgstr "Monkey's Audio Codec (*.ape)" msgid "Modules (*.xm, *.mod, *.it, *.s3m, ...)" msgstr "Module (*.xm, *.mod, *.it, *.s3m, …)" msgid "Compressed modules (*.gz, *.bz2)" msgstr "Komprimierte Module (*.gz, *.bz2)" msgid "Compressed modules (*.gz)" msgstr "Komprimierte Module (*.gz)" msgid "Compressed modules (*.bz2)" msgstr "Komprimierte Module (*.bz2)" msgid "WavPack (*.wv)" msgstr "WavPack (*.wv)" msgid "LAVC audio/video files" msgstr "LAVC-Audio/Video-Dateien" msgid "Resume" msgstr "Fortsetzen" msgid "Calculating volume level" msgstr "Lautstärke wird gemessen" msgid "Profile: Telephone" msgstr "Profil: Telephon" msgid "Profile: Thumb" msgstr "Profil: Daumen" msgid "Profile: Radio" msgstr "Profil: Radio" msgid "Profile: Standard" msgstr "Profil: Standard" msgid "Profile: Xtreme" msgstr "Profil: Extrem" msgid "Profile: Insane" msgstr "Profil: Wahnsinnig" msgid "Profile: Braindead" msgstr "Profil: Hirntot" msgid "Layer I" msgstr "Schicht I" msgid "Layer II" msgstr "Schicht II" msgid "Layer III" msgstr "Schicht III" msgid "Unrecognized" msgstr "Unbekannt" msgid "Single channel" msgstr "Einkanal" msgid "Dual channel" msgstr "Zweikanal" msgid "Joint stereo" msgstr "Verbundenes Stereo" msgid "Stereo" msgstr "Stereo" msgid "Emphasis: none" msgstr "Betonung: keine" msgid "Emphasis:" msgstr "Betonung:" msgid "Emphasis: reserved" msgstr "Betonung: reserviert" msgid "bit signed" msgstr "Bit vorzeichenbehaftet" msgid "bit unsigned" msgstr "Bit vorzeichenlos" msgid "bit float" msgstr "Bit Fließkomma" msgid "bit double" msgstr "Bit doppelt" msgid "encoding" msgstr "Kodierung" msgid "Compression: Fast" msgstr "Kompression: Schnell" msgid "Compression: Normal" msgstr "Kompression: Normal" msgid "Compression: High" msgstr "Kompression: Hoch" msgid "Compression: Extra High" msgstr "Kompression: Extra Hoch" msgid "Compression: Insane" msgstr "Kompression: Wahnsinnig" aqualung-0.9beta11/src/po/fr.po0000644000175000001440000021737411331334210013273 00000000000000# French translation for aqualung # Copyright (C) 2010 Tom Szilagyi # This file is distributed under the same license as the aqualung package. # Julien Lavergne , 2010; # Louis Opter , 2010 Almost everything, # # Please note that this translation was done in a rush. # # The quality is not as good as the original. A lot of work is needed to # review and adjust this translation. # # Feel free to contact me (Kalessin) on freenode, jabber (kalessin@jabber.fr) # or by mails. msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2010-01-12 22:03+0100\n" "PO-Revision-Date: 2010-01-31 12:50+0100\n" "Last-Translator: Louis Opter \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" msgid "About" msgstr "A propos" msgid "Build version: " msgstr "Version générée :" msgid "Homepage:" msgstr "Page d'accueil :" msgid "Authors:" msgstr "Auteurs :" msgid "Core design, engineering & programming:\n" msgstr "Architecture, développement & programmation :\n" msgid "Skin support, look & feel, GUI hacks:\n" msgstr "Support des thèmes, apparence, bidouilles de l'interface :\n" msgid "Programming, GUI engineering:\n" msgstr "Programmation et conception de l'interface graphique :\n" msgid "OpenBSD compatibility, metadata tweaks:\n" msgstr "Compatibilité OpenBSD, bidouilles des meta-données :\n" msgid "Translators:" msgstr "Traducteurs :" msgid "German:\n" msgstr "Allemand :\n" msgid "Hungarian:\n" msgstr "Hongrois :\n" msgid "Italian:\n" msgstr "Italien :\n" msgid "Japanese:\n" msgstr "Japonnais :\n" msgid "Russian:\n" msgstr "Russe :\n" msgid "Swedish:\n" msgstr "Suédois :\n" msgid "Ukrainian:\n" msgstr "Ukrainien :\n" msgid "Graphics:" msgstr "Graphismes :" msgid "Logo, icons:\n" msgstr "Logo, icônes :\n" msgid "This Aqualung binary is compiled with:" msgstr "Ce binaire d'Aqualung est compilé avec :" msgid "Optional features:" msgstr "Fonctionnalités optionnelles" msgid "LADSPA plugin support\n" msgstr "Support du plugin LADSPA\n" msgid "CDDA (Audio CD) support\n" msgstr "Support CDDA (CD Audio)\n" msgid "CDDB support\n" msgstr "Support CDDB\n" msgid "Sample Rate Converter support\n" msgstr "Conversion du taux d'échantillonage\n" msgid "iRiver iFP driver support\n" msgstr "Support du pilote iRiver iFP\n" msgid "Loop playback support\n" msgstr "Support de lecture en boucle\n" msgid "Systray support\n" msgstr "Support de la zone de notification\n" msgid "Podcast support\n" msgstr "Support du Podcast\n" msgid "Lua (programmable title formatting) support\n" msgstr "Support de Lua (formatage programmable des titres)\n" msgid "Decoding support:" msgstr "Support du décodage :" msgid "sndfile (WAV, AIFF, etc.)\n" msgstr "sndfile (WAV, AIFF, etc.)\n" msgid "Free Lossless Audio Codec (FLAC)\n" msgstr "Free Lossless Audio Codec (FLAC)\n" msgid "Ogg Vorbis\n" msgstr "Ogg Vorbis\n" msgid "Ogg Speex\n" msgstr "Ogg Speex\n" msgid "MPEG Audio (MPEG 1-2.5 Layer I-III)\n" msgstr "MPEG Audio (MPEG 1-2.5 Layer I-III)\n" msgid "MOD Audio (MOD, S3M, XM, IT, etc.)\n" msgstr "MOD Audio (MOD, S3M, XM, IT, etc.)\n" msgid "Musepack\n" msgstr "Musepack\n" msgid "Monkey's Audio Codec\n" msgstr "Codec Monkey's Audio\n" msgid "WavPack\n" msgstr "WavPack\n" msgid "LAVC (AC3, AAC, WavPack, WMA, etc.)\n" msgstr "LAVC (AC3, AAC, WavPack, WMA, etc.)\n" msgid "Encoding support:" msgstr "Support de l'encodage :" msgid "sndfile (WAV)\n" msgstr "sndfile (WAV)\n" msgid "LAME (MP3)\n" msgstr "LAME (MP3)\n" msgid "Output driver support:" msgstr "Pilotes audio supportés :" msgid "sndio Audio\n" msgstr "sndio Audio\n" msgid "OSS Audio\n" msgstr "OSS Audio\n" msgid "ALSA Audio\n" msgstr "ALSA Audio\n" msgid "JACK Audio Server\n" msgstr "JACK Audio Server\n" msgid "PulseAudio\n" msgstr "PulseAudio\n" msgid "Win32 Sound API\n" msgstr "Win32 Sound API\n" msgid "Win32 Sound API\n" "This program is free software; you can redistribute it and/or modify it " "under the terms of the GNU General Public License as published by the Free " "Software Foundation; either version 2 of the License, or (at your option) " "any later version.\n" "\n" "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.\n" "\n" "You should have received a copy of the GNU General Public License along with " "this program; if not, write to the Free Software Foundation, Inc., 675 Mass " "Ave, Cambridge, MA 02139, USA." msgstr "Win32 Sound API\n" "Ce programme est un logiciel libre ; vous pouvez le redistribuer ou le" "modifier suivant les termes de la “GNU General Public License” telle que" "publiée par la Free Software Foundation : soit la version 2 de cette" "licence, soit (à votre gré) toute version ultérieure.\n" "\n" "Ce programme est distribué dans l’espoir qu’il vous sera utile, mais SANS" "AUCUNE GARANTIE : sans même la garantie implicite de COMMERCIALISABILITÉ" "ni d’ADÉQUATION À UN OBJECTIF PARTICULIER. Consultez la Licence Générale" "Publique GNU pour plus de détails\n." "\n" "Vous devriez avoir reçu une copie de la Licence Générale Publique GNU avec" "ce programme ; si ce n’est pas le cas, écrivez à Free Software Foundation," "Inc., 675 Mass Ave, Cambridge, MA 02139, USA." msgid "Enabled" msgstr "Activé" msgid "Source" msgstr "Source" msgid "CDDB" msgstr "CDDB" msgid "CDDB (not available)" msgstr "CDDB (non disponible)" msgid "Metadata" msgstr "Meta-données" msgid "Filesystem" msgstr "Système de fichiers" msgid "Capitalization" msgstr "Capitalisation" msgid "Capitalize: " msgstr "Capitaliser : " msgid "All words" msgstr "Tous les mots" msgid "First word only" msgstr "Premier mot seulement" msgid "Force case: " msgstr "Forcer la casse : " msgid "Force other letters to lowercase" msgstr "Forcer les autres lettres en minuscule" msgid "Regular expression" msgstr "Expression régulière" msgid "Regexp:" msgstr "Expression :" msgid "Replace:" msgstr "Remplacer :" msgid "Predefined transformations" msgstr "Transformations prédéfinies" msgid "Remove file extension" msgstr "Retirer l'extension du fichier" msgid "Remove leading number" msgstr "Retirer les premiers chiffres" msgid "Convert underscore to space" msgstr "Convertir les tirets bas en espaces" msgid "Trim leading, tailing and duplicate spaces" msgstr "Enlever les espaces en trop devant et derrière" msgid "Regexp matches empty string" msgstr "L'expression regulière correspond à une chaîne vide" msgid "Please select the root directory." msgstr "Merci de sélectionner le dossier racine." msgid "Select build type" msgstr "Sélectionnez le type de génération" msgid "Directory driven" msgstr "Gérer par les dossiers" msgid "" "Follows the directory structure to identify the artists and\n" "records. The files are added on a record basis." msgstr "" "Suivre la structure des dossiers pour identifier les artistes\n" "et les albums. Les fichiers seront ajoutés sur la base des albums." msgid "Independent" msgstr "Indépendant" msgid "" "Recursive search from the root directory for audio files.\n" "The files are processed independently, so only metadata\n" "and filename transformation are available." msgstr "" "Recherche récursive sur le dossier racine pour les fichiers audio.\n" "Les fichiers sont traités indépendamment, donc seulement les méta-données\n" "et les transformations de noms de fichiers seront disponibles." msgid "Load settings from Music Store file" msgstr "Charge les réglages de fichier Music Store" msgid "Build/Update store" msgstr "Contruire/Mettre à jour la discothèque" msgid "General" msgstr "Général" msgid "Directory structure" msgstr "Structure du dossier" msgid "Root path:" msgstr "Emplacement racine :" msgid "_Browse..." msgstr "_Parcourir..." msgid "Structure:" msgstr "Structure :" msgid "root / record / track" msgstr "Racine / Album / Piste" msgid "root / artist / record / track" msgstr "Racine / Artiste / Album / Piste" msgid "root / artist / artist / record / track" msgstr "Racine / Artiste / Artiste / Album / Piste" msgid "root / artist / artist / artist / record / track" msgstr "Racine / Artiste / Artiste / Artiste/ Album / Piste" msgid "Exclude files matching wildcard" msgstr "Exclure les fichiers qui correspondent aux jokers" msgid "Include only files matching wildcard" msgstr "Inclure seulement les fichiers qui correspondent aux jokers" msgid "Reread data for existing tracks" msgstr "Re-lit les données des pistes existantes" msgid "Remove non-existing files from store" msgstr "Retirer les fichiers qui n'existent plus dans la discothèque" msgid "Artist" msgstr "Artiste" msgid "Sort artists by" msgstr "Classe les artistes par" msgid "Artist name" msgstr "Nom de l'artiste" msgid "Artist name (lowercase)" msgstr "Nom de l'artiste (minuscules)" msgid "Directory name" msgstr "Nom du dossier" msgid "Directory name (lowercase)" msgstr "Nom du dossier (minuscules)" msgid "Record" msgstr "Album" msgid "Sort records by" msgstr "Classe les albums par" msgid "Record name" msgstr "Nom de l'album" msgid "Record name (lowercase)" msgstr "Nom de l'enregistrement (minuscule)" msgid "Year" msgstr "Année" msgid "Add year to the comments of new records" msgstr "Ajouter l'année aux commentaires des nouveaux albums" msgid "Track" msgstr "Piste" msgid "Import Replaygain tag as manual RVA" msgstr "Importer l'étiquette Replaygain comme des RVA manuels" msgid "Import Comment tag" msgstr "Importer l'étiquette Commentaire" msgid "Sandbox" msgstr "Bac à sable" msgid "Filename:" msgstr "Nom du fichier :" msgid "Test" msgstr "Test" msgid "Building store from filesystem" msgstr "Construire la discothèque à partir du système de fichiers" msgid "Processing:" msgstr "Traitement :" msgid "Action:" msgstr "Action :" msgid "Abort" msgstr "Abandon" msgid "Unknown Artist" msgstr "Artiste inconnu" msgid "Unknown Record" msgstr "Album inconnu" msgid "Scanning files" msgstr "Analyse des fichiers" msgid "Processing metadata" msgstr "Traitement des meta-données" msgid "CDDB lookup" msgstr "Interogation de CDDB" msgid "Name transformation" msgstr "Transformation du nom" msgid "Reading file" msgstr "Lecture du fichier" msgid "Removing non-existing files" msgstr "Enlever les fichiers inexistants" msgid "Unknown disc" msgstr "Disque inconnu" msgid "No disc" msgstr "Pas de disque" msgid "CDDB query" msgstr "Requête vers CDDB" msgid "Retrieving matches from server..." msgstr "Récupération des correspondances depuis le serveur..." msgid "Connecting to CDDB server..." msgstr "Connexion au serveur CDDB..." msgid "Error" msgstr "Erreur" msgid "An error occurred while attempting to connect to the CDDB server." msgstr "Une erreur est survenue lors de la connexion au serveur CDDB." msgid "Warning" msgstr "Attention" msgid "No matching record found." msgstr "Pas d'album correspondant trouvé." msgid "Import as Sort Key" msgstr "Importer comme clé de tri" msgid "Import as Title" msgstr "Importer comme un titre" msgid "Import as Year" msgstr "Importer comme une année" msgid "" "Artist appears to be in all lowercase.\n" "Do you want to proceed?" msgstr "" "L'artiste est entièrement en minuscules.\n" "Voulez vous continuer ?" msgid "" "Artist appears to be in all uppercase.\n" "Do you want to proceed?" msgstr "" "L'artiste est entièrement en majuscules.\n" "Voulez vous continuer ?" msgid "" "Title appears to be in all lowercase.\n" "Do you want to proceed?" msgstr "" "Le titre est entièrement en minuscules.\n" "Voulez vous continuer ?" msgid "" "Title appears to be in all uppercase.\n" "Do you want to proceed?" msgstr "" "Le titre est entièrement en majuscules.\n" "Voulez vous continuer ?" msgid "" "It is very likely that the year is wrong.\n" "Do you want to proceed?" msgstr "" "Il est très probable que l'année soit fausse.\n" "Voulez vous continuer ?" msgid "The email address provided for submission is invalid." msgstr "L'adresse de courriel fournie pour la proposition est invalide." msgid "An error occurred while submitting the record to the CDDB server." msgstr "Une erreur est survenue lors de la proposition de l'album au serveur CDDB" msgid "Correct existing record" msgstr "Correction de l'album existant" msgid "Submit new record" msgstr "Soumettre un nouvel album" msgid "Matches:" msgstr "Concordances :" msgid "Artist:" msgstr "Artiste :" msgid "Title:" msgstr "Titre :" msgid "Year:" msgstr "Année :" msgid "Category:" msgstr "Catégorie :" msgid "(choose a category)" msgstr "(choisir une catégorie)" msgid "Genre:" msgstr "Genre :" msgid "Extended data:" msgstr "Données étendues :" msgid "Import as Artist" msgstr "Importer comme Artiste" msgid "Add to Comments" msgstr "Ajouter aux commentaires" msgid "Tracks" msgstr "Pistes" msgid "You have to provide an email address for CDDB submission." msgstr "Vous devez fournir une adresse de courriels pour faire une proposition sur CDDB" msgid "Please select the directory for ripped files." msgstr "Sélectionnez le dossier pour les fichiers copiés." msgid "(none)" msgstr "(rien)" msgid "fast" msgstr "rapide" msgid "best" msgstr "meilleur" msgid "Compression level:" msgstr "Niveau de compression :" msgid "Bitrate [kbps]:" msgstr "Bitrate [kbps] :" msgid "Artist/Album already existing, not empty" msgstr "Artiste/Album déjà existant, non vide" msgid "" "\n" "The Music Store you selected has a matching Artist and Album, already " "containing some tracks. If you press OK, these tracks will be removed. The " "files themselves will be left intact, but they will be removed from the " "destination Music Store. Press Cancel to get back to change the Artist/Album " "or the destination Music Store." msgstr "" "\n" "La Discothèque que vous avez sélectionné a une correspondance avec un Artiste et un Album " "contenant déjà certaines pistes. Si vous appuyez sur OK, ces pistes seront enlevées. Les " "fichiers eux mêmes seront laissés intacts, mais ils seront enlevé " "de la Discothèque cible. Appuyez sur Annuler pour revenir en arrière pour changer les Artistes/Albums" "ou la Discothèque cible." msgid "Rip CD" msgstr "Copier un CD" msgid "Album:" msgstr "Album :" msgid "Rip" msgstr "Copier" msgid "No." msgstr "No." msgid "Title" msgstr "Titre" msgid "Select" msgstr "Sélectioner" msgid "All" msgstr "Tout" msgid "None" msgstr "Aucun" msgid "Output" msgstr "Sortie" msgid "Destination" msgstr "Destination" msgid "Target directory for ripped files" msgstr "Dossier cible pour les fichiers rippés" msgid "Add to Music Store" msgstr "Ajouter dans la Discothèque" msgid "Format" msgstr "Format" msgid "File format:" msgstr "Format du fichier :" msgid "VBR encoding" msgstr "Encodage VBR" msgid "Tag files with metadata" msgstr "Étiquetter les fichiers avec les méta-données" msgid "Paranoia" msgstr "Paranoia" msgid "Paranoia error correction" msgstr "Erreur de connexion à Paranoia" msgid "Perform overlapped reads" msgstr "Effectue des lectures" msgid "Verify data integrity" msgstr "Vérifie l'intégrité des données" msgid "Unlimited retry on failed reads (never skip)" msgstr "Toujours réessayer une lecture échouée" msgid "Maximum number of retries:" msgstr "Nombre maximal de tentatives :" msgid "" "\n" "Destination directory is not read-write accessible!" msgstr "" "\n" "Le dossier cible n'est pas accessible en lecture et en écriture." msgid "Total" msgstr "Total" msgid "(audio only)" msgstr "(audio seulement)" msgid "Ripping CD tracks" msgstr "Copie des pistes du CD" msgid "Begin" msgstr "Début" msgid "Length" msgstr "Duré" msgid "Progress" msgstr "Progression" msgid "Close window when complete" msgstr "Fermer la fenêtre une fois terminé" msgid "Close" msgstr "Fermer" msgid "Unknown Album" msgstr "Album inconnu" msgid "Unknown Track" msgstr "Piste inconnue" msgid "Please select the directory for exported files." msgstr "Veuillez choisir un dossier où exporter les fichiers." msgid "Copy" msgstr "Copier" msgid "Help" msgstr "Aide" #, c-format msgid "" "\n" "The template string you enter here will be used to construct the filename of " "the exported files. The Artist, Record and Track names are denoted by %%%%a, " "%%%%r and %%%%t. The track number and format-dependent file extension are " "denoted by %%%%n and %%%%x, respectively. The flag %%%%i gives an identifier " "which is unique within an export session." msgstr "" "\n" "Le patron de chaîne de caractères que vous entrez ici sera utilisé pour " "générer les noms des fichiers exportés. L'artiste, l'album et le nom des " "pistes sont notés par %%%%a, %%%%r et %%%%t. Le numéro de piste et " "l'extension du fichier sont respectivement notés %%%%n et %%%%x. Le " "drapeau %%%%i donne un identifiant qui est unique pour une session " "d'export." msgid "Export files" msgstr "Exporter les fichiers" msgid "Location and filename" msgstr "Destination et nom du fichier" msgid "Target directory:" msgstr "Dossier cible :" msgid "Create subdirectories for artists" msgstr "Créer des sous-dossiers pour les artistes" msgid "Create subdirectories for albums" msgstr "Créer des sous-dossiers pour les albums" msgid "" "Subdirectory name\n" "length limit:" msgstr "" "Longueur maximale\n" "du nom du sous-dossier:" msgid "Filename template:" msgstr "Patron du nom du fichier :" msgid "Filter" msgstr "Filtre" msgid "Do not reencode files already being in the target format" msgstr "Ne pas encoder de nouveau les fichiers qui sont déjà dans le bon format" msgid "" "Do not reencode files\n" "matching wildcard:" msgstr "" "Ne pas encoder de nouveaux les fichiers\n" "qui correspondent à ce joker:" msgid "Error in format string" msgstr "Erreur dans la chaîne de format" msgid "Exporting files" msgstr "Export des fichiers..." msgid "Source file:" msgstr "Fichier source :" msgid "Target file:" msgstr "Fichier cible :" msgid "Progress:" msgstr "Progression :" msgid "*File info" msgstr "*Informations sur le fichier" msgid "File info" msgstr "Informations sur le fichier" msgid "There are unsaved changes to the file metadata." msgstr "Il y a des changements en cours sur les meta-données du fichier." msgid "Save and close" msgstr "Sauvegarder et quitter" msgid "Discard changes" msgstr "Abandonner les changements" msgid "Do not close" msgstr "Ne pas fermer" #, c-format msgid "" "Conversion error in field %s:\n" "'%s' does not conform to format '%s'!" msgstr "Erreur de conversion dans le champs %s :\n" "'%s' ne correspond pas au format '%s'!" msgid "" "Attached Picture frame with no image set!\n" "Please set an image or remove the frame." msgstr "" "Un cadre pour une image est présent mais pas l'image !\n" "Mettez une image ou enlevez le cadre." #, c-format msgid "" "Failed to write metadata to file.\n" "Reason: %s" msgstr "" "Impossible d'enregistrer les méta-données.\n" "Raison : %s" #, c-format msgid "" "Error converting field %s to Year:\n" "'%s' is not an integer number!" msgstr "" "Erreur lors de la conversion du champs %s vers Année :\n" "'%s' n'est pas un nombre entier !" msgid "Please specify the file to save the image to." msgstr "Choisissez où enregistrer l'image." msgid "(no image)" msgstr "(pas d'image)" msgid "(error loading image)" msgstr "(erreur lors du chargement de l'image)" msgid "Please specify the file to load the image from." msgstr "Choisissez une image." #, c-format msgid "" "Could not load image from:\n" "%s" msgstr "" "Impossible de charger l'image:\n" "%s" #, c-format msgid "MIME type: %s" msgstr "type MIME : %s" msgid "Picture type:" msgstr "Type d'image :" msgid "Description:" msgstr "Description :" msgid "(no description)" msgstr "(pas de description)" msgid "Change" msgstr "Changer" msgid "Save" msgstr "Enregistrer" msgid "Import as Record" msgstr "Importer en tant qu'Album" msgid "Import as Track No." msgstr "Importrer en tant que numéro de piste" msgid "Import as RVA" msgstr "Importer en tant que RVA" msgid "Add" msgstr "Ajouter" msgid "field:" msgstr "champs :" msgid "tag:" msgstr "étiquette :" msgid "Audio CD" msgstr "CD Audio" msgid "Track:" msgstr "Piste :" msgid "File:" msgstr "Fichier :" msgid "Audio data" msgstr "Données audio" msgid "Format:" msgstr "Format :" msgid "Length:" msgstr "Duręe :" msgid "Samplerate:" msgstr "Taux d'échantillonage :" #, c-format msgid "%ld Hz" msgstr "%ld Hz" msgid "Channel count:" msgstr "Nombre de canaux :" msgid "MONO" msgstr "MONO" msgid "STEREO" msgstr "STEREO" msgid "Bandwidth:" msgstr "Bande passante :" msgid "Total samples:" msgstr "Nombre d'échantillons" msgid "Mode:" msgstr "Mode :" msgid "Type:" msgstr "Type :" msgid "Channels:" msgstr "Canaux :" msgid "Patterns:" msgstr "Motifs :" msgid "Samples:" msgstr "Échantillons :" msgid "Instruments:" msgstr "Instruments :" msgid "Samples" msgstr "Échantillons" msgid "Instruments" msgstr "Instruments" msgid "Name" msgstr "Nom" msgid "STOPPING" msgstr "ARRÊT" msgid "Output:" msgstr "Sortie :" msgid "No output" msgstr "Pas de sortie" msgid "SRC Type: " msgstr "Type de source :" #, c-format msgid "Loop range: %d-%d%% [%s - %s]" msgstr "" #, c-format msgid "Loop range: %d-%d%%" msgstr "" msgid "" "One or more stores in Music Store have been modified.\n" "Do you want to save them before exiting?" msgstr "" "Des discothèques ont été modifiées.\n" "Souhaitez vous les sauvegarder avant de quitter ?" msgid "Do not exit" msgstr "Ne pas quitter" msgid "Quit" msgstr "Quitter" #, c-format msgid "Position: %d%%" msgstr "Position : %s%%" #, c-format msgid "Mute" msgstr "Muet" #, c-format msgid "%d dB" msgstr "" #, c-format msgid "Volume: %s" msgstr "" #, c-format msgid "%d%% R" msgstr "" #, c-format msgid "%d%% L" msgstr "" #, c-format msgid "C" msgstr "" #, c-format msgid "Balance: %s" msgstr "Équilibrage : %s" msgid "JACK connection lost" msgstr "Connexion avec JACK perdue" msgid "" "JACK has either been shutdown or it disconnected Aqualung because it was not " "fast enough. All you can do now is restart both JACK and Aqualung." msgstr "" "Soit JACK a été éteint soit il a déconnecté Aqualung car il n'était pas assez " "rapide. Vous n'avez pas d'autres choix que de relancer JACK et Aqualung." msgid "Warn me if the Window Manager does not support system tray" msgstr "Me prévenir si le gestionnaire de fenêtre ne supporte pas la zone " "de notifications" msgid "" "Aqualung is compiled with system tray support, but the status icon could not " "be embedded in the notification area. Your desktop may not have support for " "a system tray, or it has not been configured correctly." msgstr "" "Aqualung n'arrive pas à utiliser la zone de notification. Peut-être que votre " "gestionnaire de fenêtre ne supporte pas la zone de notification ou qu'il est " "mal configuré." msgid "Settings" msgstr "Préférences" msgid "Skin chooser" msgstr "Changer d'apparence" msgid "JACK port setup" msgstr "Configuration de JACK" msgid "Previous song" msgstr "Piste précédente" msgid "Stop" msgstr "" msgid "Next song" msgstr "Piste suivante" msgid "Play/Pause" msgstr "Lecture/Pause" msgid "Play" msgstr "Lecture" msgid "Pause" msgstr "Pause" msgid "Repeat current song" msgstr "Répéter la piste courante" msgid "Repeat all songs" msgstr "Répéter la liste de lecture" msgid "Shuffle songs" msgstr "Mélanger les pistes" msgid "Toggle playlist" msgstr "Afficher la liste de lecture" msgid "Toggle music store" msgstr "Afficher la discothèque" msgid "Toggle LADSPA patch builder" msgstr "Afficher les filtres LADSPA" msgid "Show Aqualung" msgstr "Afficher Aqualung" msgid "Hide Aqualung" msgstr "Cacher Aqualung" msgid "Previous" msgstr "Précédent" msgid "Next" msgstr "Suivant" #, c-format msgid "%.1f MB / %.1f MB" msgstr "%.1f MO / %.1f MO" #, c-format msgid "%d / %d files" msgstr "%d / %d fichiers" #, c-format msgid "%d / %d directories" msgstr "%d / %d dossiers" msgid "Cannot write to selected directory. Please select another directory." msgstr "Impossible d'écrire vers le dossier sélectionné. Veuillez en choisir un autre." msgid "Done" msgstr "Fini" msgid "Aborted..." msgstr "Abandonné..." msgid "Please enter directory name." msgstr "Veuillez entrer le nom d'un dossier." msgid "Create directory" msgstr "Créer un dossier" msgid "Please enter a new name." msgstr "Veuillez entrer le nouveau nom." msgid "Rename" msgstr "Renommer" #, c-format msgid "" "Directory '%s' will be removed with its entire contents.\n" "\n" "Do you want to proceed?" msgstr "" "Le dossier '%s' sera effacé avec tout ce qu'il contient.\n" "\n" "Voulez vous continuer ?" #, c-format msgid "" "File '%s' will be removed.\n" "\n" "Do you want to proceed?" msgstr "" "Le fichier '%s' sera effacé.\n" "\n" "Voulez vous continuer ?" msgid "Remove" msgstr "Effacer" #, c-format msgid " (%.1f MB)" msgstr " (%.1f MO)" #, c-format msgid " (capacity = %.1f MB)" msgstr " (capacité = %.1f MO)" #, c-format msgid " Free space (%.1f MB)" msgstr " Espace libre (%.1f MO)" msgid "" "No suitable iRiver iFP device found.\n" "Perhaps it is unplugged or turned off." msgstr "" "Aucun périphérique iRiver iFP utilisable n'a été trouvé.\n" "Peut-être qu'il n'est pas branché ou qu'il est éteint." msgid "" "Device is busy.\n" "(Aqualung was unable to claim its interface.)" msgstr "" "Le périphérique est déjà utilisé.\n" "(Aqualung n'a pas pus réclamer son utilisation.)" msgid "" "Device is not responding.\n" "Try jiggling the handle." msgstr "Le périphérique ne répond pas." msgid "Please select a local path." msgstr "Veuillez sélectionner un chemin local." msgid "Please select at least one valid song from playlist." msgstr "Veuillez sélectionner au moins une piste valide depuis la liste de lecture." #, c-format msgid "" "One song has format unsupported by your player.\n" "\n" "Do you want to proceed?" msgstr "" "Une des pistes est dans un format qui n'est pas supporté par votre lecteur.\n" "\n" "Voulez vous continuer ?" #, c-format msgid "" "%d of %d songs have format unsupported by your player.\n" "\n" "Do you want to proceed?" msgstr "" "%d sur %d pistes sont dans un format qui n'est pas supporté par votre lecteur.\n" "\n" "Voulez vous continuer ?" #, c-format msgid "" "The selected song has format unsupported by your player.\n" "\n" "Do you want to proceed?" msgstr "" "La piste sélectionnée est dans un format qui n'est pas supporté par votre lecteur.\n" "\n" "Voulez vous continuer ?" #, c-format msgid "" "None of the selected songs has format supported by your player.\n" "\n" "Do you want to proceed?" msgstr "" "Aucune des pistes que vous avez sélectionnées ne sont supportées par votre lecteur.\n" "\n" "Voulez vous continuer ?" msgid "iFP device manager (upload mode)" msgstr "Gestionnaire de périphérique iFP (mode d'envoi)" msgid "iFP device manager (download mode)" msgstr "Gestionnaire de périphérique iFP (mode de téléchargement)" msgid "Selected files:" msgstr "Fichiers sélectionnés :" msgid "Songs info" msgstr "Informations sur les pistes" msgid "Model:" msgstr "Modèle :" msgid "Battery" msgstr "Batterie :" msgid "Free space" msgstr "Espace libre" msgid "Device status" msgstr "État du périphérique" msgid "Size" msgstr "Taille" msgid "Create a new directory" msgstr "Créer un nouveau dossier" msgid "Remote directory" msgstr "Dossier distant" msgid "Local directory" msgstr "Dossier local" msgid "Browse" msgstr "Explorer" msgid "File name: " msgstr "Nom du fichier : " msgid "Current file: " msgstr "Fichier courant : " msgid "Overall: " msgstr "Total : " msgid "Idle" msgstr "En attente" msgid "Transfer progress" msgstr "Status du transfert" msgid "Close window when transfer complete" msgstr "Fermer la fenêtre quand le transfert est terminé" msgid "_Upload" msgstr "_Envois" msgid "_Download" msgstr "_Téléchargement" msgid "_Abort" msgstr "_Annuler" msgid "Success" msgstr "Succès" msgid "Memory allocation error" msgstr "Impossible d'allouer de la mémoire" msgid "Unable to open file" msgstr "Impossible d'ouvrir le fichier" msgid "No metadata support for this format" msgstr "Pas de support des méta-données pour ce format" msgid "File is not writable" msgstr "Le fichier n'est pas accessible en écriture" msgid "Invalid 'Track no.' field value" msgstr "La valeur du champs 'No. de Piste' n'est pas valide" msgid "Invalid 'Genre' field value" msgstr "La valeur du champs 'Genre' n'est pas valide" msgid "Conversion to target charset failed" msgstr "La conversion vers le nouveau format d'encodage des caractères a échoué" msgid "Internal error" msgstr "Erreur interne" msgid "Unknown error" msgstr "Erreur inconnue" msgid "Album" msgstr "Album" msgid "Date" msgstr "Date" msgid "Genre" msgstr "Genre" msgid "Track No." msgstr "Piste No." msgid "Comment" msgstr "Commentaire" msgid "Disc" msgstr "Disque" msgid "Performer" msgstr "Interprète" msgid "Description" msgstr "Description" msgid "Organization" msgstr "Organisation" msgid "Location" msgstr "Lieu" msgid "Contact" msgstr "Contact" msgid "License" msgstr "Licence" msgid "Copyright" msgstr "Copyright" msgid "ISRC" msgstr "ISRC" msgid "Version" msgstr "Version" msgid "Subtitle" msgstr "Sous-titre" msgid "Debut Album" msgstr "Premier Album" msgid "Publisher" msgstr "Éditeur" msgid "Conductor" msgstr "Chef d'orchestre" msgid "Composer" msgstr "Compositeur" msgid "Publication Right" msgstr "Droit de publication" msgid "File" msgstr "Fichier" msgid "EAN/UPC" msgstr "EAN/UPC" msgid "ISBN" msgstr "ISBN" msgid "Catalog Number" msgstr "Numéro du catalogue" msgid "Label Code" msgstr "Identifiant du Label" msgid "Record Date" msgstr "Date d'enregistrement" msgid "Record Location" msgstr "Lieu d'enregistrement" msgid "Media" msgstr "Media" msgid "Index" msgstr "Index" msgid "Related" msgstr "Lié à" msgid "Abstract" msgstr "Résumé" msgid "Language" msgstr "Langue" msgid "Bibliography" msgstr "Bibliographie" msgid "Introplay" msgstr "" msgid "BPM" msgstr "BPM" msgid "Encoding Time" msgstr "Date d'encodage" msgid "Playlist Delay" msgstr "Duré du Silence Entre les Pistes (ms)" msgid "Original Release Time" msgstr "Date de Sortie Originale" msgid "Release Time" msgstr "Date de Sortie" msgid "Tagging Time" msgstr "Date de l'Étiquettage" msgid "Encoded by" msgstr "Encodé avec" msgid "Lyricist/Text Writer" msgstr "Paroles" msgid "File Type" msgstr "Format du Fichier" msgid "Involved People" msgstr "Participants" msgid "Content Group" msgstr "Style" msgid "Initial key" msgstr "Clef" msgid "Musician Credits" msgstr "Musiciens Participants" msgid "Mood" msgstr "Humeur" msgid "Original Album" msgstr "Album Original" msgid "Original Filename" msgstr "Nom Original du Fichier" msgid "Original Lyricist" msgstr "Paroles Originales" msgid "Original Artist" msgstr "Artiste Original" msgid "File Owner" msgstr "Propriétaire du Fichier" msgid "Band/Orchestra" msgstr "Groupe/Orchestre" msgid "Interpreted/Remixed" msgstr "Interprété/Remixé" msgid "Part Of A Set" msgstr "Partie d'une Compilation" msgid "Produced" msgstr "Produit" msgid "Internet Radio Station Name" msgstr "Nom de la Station Radio sur Internet" msgid "Internet Radio Station Owner" msgstr "Propriétaire de la Station Radio sur Internet" msgid "Album Sort Order" msgstr "Ordre de Tri de l'Album" msgid "Performer Sort Order" msgstr "Ordre de Tri des Interprètes" msgid "Title Sort Order" msgstr "Ordre de Tri des Titres" msgid "Software" msgstr "Logiciel" msgid "Set Subtitle" msgstr "Sous-titre de la Partie de la Compilation" msgid "User Defined Text" msgstr "Champs Définis par l'Utilisateur" msgid "Commercial Information" msgstr "Informations Commerciales" msgid "Copyright/Legal Information" msgstr "Copyright/Informations Légales" msgid "Official Audio File Website" msgstr "Site Officiel du Fichier Audio" msgid "Official Artist Website" msgstr "Site Officiel de l'Artiste" msgid "Official Audio Source Website" msgstr "Site Officel de la Source du Fichier Audio" msgid "Official Radio Station Website" msgstr "Site Officiel de la Station Radio sur Internet" msgid "Payment" msgstr "Paiement" msgid "Publisher's Official Website" msgstr "Site Officiel de l'Éditeur" msgid "User Defined URL" msgstr "URL Définie par l'Utilisateur" msgid "Vendor" msgstr "Vendeur" msgid "ReplayGain Reference Loudness" msgstr "Référence ReplayGain du Bruit" msgid "ReplayGain Track Gain" msgstr "Gain ReplayGain de la Piste" msgid "ReplayGain Track Peak" msgstr "Pic ReplayGain de la Piste" msgid "ReplayGain Album Gain" msgstr "Gain ReplayGain de l'Album" msgid "ReplayGain Album Peak" msgstr "Pic ReplayGain de l'Album" msgid "Icy-Name" msgstr "Noms des Stations" msgid "Icy-Description" msgstr "Descriptions" msgid "Icy-Genre" msgstr "Genre" msgid "RVA" msgstr "RVA" msgid "Attached Picture" msgstr "Image attachée" msgid "Binary Object" msgstr "Objet Binaire" msgid "NULL" msgstr "" msgid "ID3v1" msgstr "" msgid "ID3v2" msgstr "" msgid "APE" msgstr "" msgid "Ogg Xiph Comments" msgstr "Commentaires Ogg Xiph" msgid "FLAC Pictures" msgstr "Images FLAC" msgid "Musepack ReplayGain" msgstr "ReplayGain Musepack" msgid "Generic StreamMeta" msgstr "Méta-données du Flux" msgid "MPEG StreamMeta" msgstr "Méta-données du Flux MPEG" msgid "Module info" msgstr "Informations du Module" msgid "Unknown" msgstr "Inconnu" msgid "Other" msgstr "Autre" msgid "File icon (32x32 PNG)" msgstr "Icône du fichier (PNG 32x32)" msgid "File icon (other)" msgstr "Icône du fichier (autre)" msgid "Front cover" msgstr "Front de la couverture" msgid "Back cover" msgstr "Arrière de la couverture" msgid "Leaflet page" msgstr "Brochure" msgid "Album image" msgstr "Image de l'Album" msgid "Lead artist/performer" msgstr "Artiste/Interprète principal" msgid "Artist/performer" msgstr "Artiste/Interprète" msgid "Band/orchestra" msgstr "Groupe/Orchestre" msgid "Lyricist/text writer" msgstr "Paroles" msgid "Recording location/studio" msgstr "Lieu/Studio d'enregistrement" msgid "During recording" msgstr "Pendant l'enregistrement" msgid "During performance" msgstr "Pendant l'interprètation" msgid "Movie/video screen capture" msgstr "Capture d'un film/video" # srsly, wtf ? Et c'est dans les putains de specs id3v2... msgid "A large, coloured fish" msgstr "Un poisson lumineux et coloré" msgid "Illustration" msgstr "Illustration" msgid "Band/artist logotype" msgstr "Logo du groupe/artiste" msgid "Publisher/studio logotype" msgstr "Logo du studio/éditeur" msgid "Music Store" msgstr "Discothèque" msgid "Search..." msgstr "Rechercher..." msgid "Collapse all items" msgstr "Replier tous les éléments" msgid "Edit item..." msgstr "Éditer..." msgid "Add item..." msgstr "Ajouter..." msgid "Remove item..." msgstr "Retirer..." msgid "Save all stores" msgstr "Sauvegarder toutes les discothèques" msgid "Create empty store..." msgstr "Créer une discothèque" msgid "*Music Store" msgstr "*Discothèque" #, c-format msgid "Do you want to save store \"%s\" before removing from Music Store?" msgstr "Voulez vous sauvegarder la discothèque \"%s\" avant de l'enlever ?" msgid "" "You will need to restart Aqualung for the following changes to take effect:" msgstr "" "Vous devez relancer Aqualung pour que les changements suivants prennent effet :" msgid "Select a font..." msgstr "Sélectionnez une police..." msgid "Disable skin support" msgstr "Désactiver le support des thèmes" msgid "rw" msgstr "rw" msgid "r" msgstr "r" msgid "unreachable" msgstr "injoignable" msgid "Please select a Programable Title Format File." msgstr "Veuillez sélectionner un Fichier de Format de Titres Programmables." msgid "Please select a Music Store database." msgstr "Veuillez sélectionner une discothèque." msgid "Paths must either be absolute or starting with a tilde." msgstr "Les chemins de fichiers doivent être soit absolus soit commencer avec ~" msgid "The specified store has already been added to the list." msgstr "La discothèque sélectionnée a déjà été ajoutée dans la liste." #, c-format msgid "" "\n" "The template string you enter here will be used to construct a single title " "line from an Artist, a Record and a Track name. These are denoted by %%%%a, %" "%%%r and %%%%t, respectively.\n" msgstr "" "\n" "Le patron de chaîne de caractères que vous entrez ici sera utilisé pour " "générer un titre depuis un Artiste, un Album et un numéro de Piste. Ils sont " "respectivement notés par : %%%%a, %%%%r et %%%%t.\n" msgid "" "\n" "The file you enter/choose here will set the Lua program to use to format the " "title. See the Aqualung manual for details. Here is a quick example of what " "you can use in the file:\n" "\n" "function playlist_title()\n" " return m('artist') .. '-' .. m('title') .. ' (' .. m('album') .. ') (' .. i" "('filename') .. ')'\n" "end" msgstr "" "\n" "Le fichier que vous choisissez ici représente le programme Lua à " "utiliser pour formater le titre. Consultez le manuel d'Aqualung pour les " "détails. Voici un exemple de ce que vous pouvez utiliser :\n" "\n" "function playlist_title()\n" " return m('artist') .. '-' .. m('title') .. ' (' .. m('album') .. ') (' .. i" "('filename') .. ')'\n" "end" msgid "" "\n" "The string you enter here will be parsed as a command line before parsing " "the actual command line parameters. What you enter here will act as a " "default setting and may or may not be overridden from the 'real' command " "line.\n" "\n" "Example: enter '-o alsa -R' below to use ALSA output running realtime as a " "default.\n" msgstr "" "\n" "La chaîne de caractères que vous entrez ici sera analysée avant les " "arguments donnés à Aqualung. Ce que vous entrez ici va agir comme un " "paramètre par défaut qui peut (ou pas) être surchargé depuis la 'vraie' " "ligne de commande.\n" "\n" "Exemple : entrez ci-dessous : '-o alsa -R' pour utiliser la sortie ALSA en " "temps réel par défaut.\n" msgid "" "Paths must either be absolute or starting with a tilde, which will be " "expanded to the user's home directory.\n" "\n" "Drag and drop entries in the list to set the store order in the Music Store." msgstr "" "Les chemins de fichiers doivent être absolus ou commencer avec ~, qui sera " "remplacé par le répertoire personnel de l'utilisateur.\n" "\n" "Glissez et déposez les entrées dans la liste pour configurer l'ordre de tri " "dans la Discothèque." msgid "" "\n" "Set the drive speed for CD playing in CD-ROM speed units. One speed unit " "equals to 176 kBps raw data reading speed. Warning: not all drives honor " "this setting.\n" "\n" "Lower speed usually means less drive noise. However, when using Paranoia " "error correction modes for increased accuracy, generally much larger speeds " "are required to prevent buffer underruns (and thus audible drop-outs).\n" "\n" "Please note that these settings do not apply to CD Ripping, which always " "happens with maximum available speed and with error correction modes " "manually set before every run." msgstr "" "\n" "Configurez la vitesse du lecteur CD-ROM. Une unité de vitesse correspond à " "176 kO de données brutes par seconde. Attention : certains lecteurs " "n'utilisent pas cette préférence.\n" "\n" "Des vitesses basses signifient généralement moins de bruit. Cependant, en " "utilisant les modes de corrections d'erreurs de Paranoia (pour plus de " "précision); des vitesses beaucoup plus grandes sont souvent nécessaires pour " "éviter des tampons vides (et donc des moments de blanc audibles)." "\n" "Veuillez noter que ces préférences ne s'appliquent pas lors de l'encodage de " "CD-ROM, qui ont toujours lieu à la plus grande vitesse possible et avec les " "modes de corrections d'erreurs choisis avant chaque encodage." msgid "" "\n" "Most drives let Aqualung know when a CD has been inserted or removed by " "providing a 'media changed' flag. However, some drives don't set this flag " "properly, and thus it may happen that a newly inserted CD remains unnoticed " "to Aqualung. In such cases, enabling this option should help." msgstr "" "\n" "La plupart des lecteurs notifient Aqualung quand un CD-ROM a été inséré ou " "retiŕe. Cependant, certains lecteurs ne le font pas correctement et parfois " "Aqualung ne réagit pas quand un CD-ROM a été inséré. Dans ce cas activer " "cette option peut aider." msgid "" "\n" "Here you should enter a comma-separated list of domains\n" "that should be accessed without using the proxy set above.\n" "Example: localhost, .localdomain, .my.domain.com" msgstr "" "\n" "Vous devriez entrer ici une liste de domaines séparés par des virgules\n" "qui sont accessible sans le serveur mandataire configuré plus haut.\n" "Exemple : localhost, .localdomain, .my.domain.com" msgid "Embed playlist into main window" msgstr "Intégrer la liste de lecture dans la fenêtre principale" msgid "Enable systray" msgstr "Activer la zone de notifications" msgid "Do nothing" msgstr "Ne fait rien" msgid "Change volume" msgstr "Changer le volume" msgid "Change balance" msgstr "Changer l'équilibrage" msgid "Change song position" msgstr "Changer la chanson de position" msgid "Change current song" msgstr "Changer la chanson courante" msgid "Left button" msgstr "Bouton gauche" msgid "Middle button" msgstr "Bouton du milieu" msgid "Right button" msgstr "Bouton droit" msgid "Button" msgstr "Bouton" msgid "Left and right mouse buttons are reserved." msgstr "Les boutons gauche et droit de la souris sont réservés." msgid "This button is already assigned." msgstr "Ce bouton est deja affecté." msgid "Add mouse button command" msgstr "Ajouter une commande sur le bouton de la souris" msgid "Mouse button" msgstr "Bouton de souris" msgid "Click here to set mouse button" msgstr "Cliquer ici pour configurer le bouton de la souris" msgid "Command" msgstr "Commande" msgid "Main window" msgstr "Fenêtre Principale" msgid "Disable control buttons relief" msgstr "Désactiver le relief des boutons de contrôles" msgid "Combine play and pause buttons" msgstr "Combiner les boutons pause et lecture" msgid "Keep main window always on top" msgstr "Toujours garder la fenêtre principale au dessus" msgid "Show song name in the main window's title" msgstr "Montrer le nom de la chanson dans le titre de la fenêtre principale" msgid "Title Format" msgstr "Format du Titre" msgid "Programmable title format file" msgstr "Fichier du format de titre programmable" msgid "Systray" msgstr "Zone de notification" msgid "Start minimized" msgstr "Démarrer minimisé" msgid "Play/Stop song" msgstr "Lecture/Stop" msgid "Play/Pause song" msgstr "Lecture/Pause" msgid "Mouse wheel" msgstr "Roue de la souris" msgid "Vertical mouse wheel:" msgstr "Roue verticale de la souris :" msgid "Horizontal mouse wheel:" msgstr "Roue horizontale de la souris :" msgid "Mouse buttons" msgstr "Boutons de la souris" msgid "Miscellaneous" msgstr "Divers" msgid "Implicit command line" msgstr "Ligne de commande implicite" msgid "Cover art" msgstr "Couverture" msgid "Default cover width:" msgstr "Largeur par defaut de la couverture :" msgid "50 pixels" msgstr "" msgid "100 pixels" msgstr "" msgid "200 pixels" msgstr "" msgid "300 pixels" msgstr "" msgid "use browser window width" msgstr "Utiliser la largeur de la fenêtre de navigation" msgid "Do not magnify images with smaller width" msgstr "Ne pas agrandir les images qui sont trop petites" msgid "Show cover thumbnail for Music Store tracks only" msgstr "Montrer seulement une miniature de la couverture pour les pistes dans " "la Discothèque" msgid "Don't show cover thumbnail in the main window" msgstr "Ne pas montrer la miniature de la couverture dans la fenêtre principale" msgid "Enable tooltips" msgstr "Activer les info-bulles" msgid "Simple view in LADSPA patch builder" msgstr "Vue simplifiée dans le configuration des filtres LADSPA" msgid "United windows minimization" msgstr "Minimisation de toutes les fenêtres en même temps" msgid "Show hidden files and directories in file choosers" msgstr "Montrer les fichiers et les dossiers cachés" msgid "Show tags tab first in the file info dialog" msgstr "Montrer l'onglet des étiquettes en premier dans la fenêtre " "d'information sur un fichier" msgid "Playlist" msgstr "Liste de lecture" msgid "Put control buttons at the bottom of playlist" msgstr "Placer les boutons de contrôles en dessous de la liste de lecture" msgid "Save and restore the playlist on exit/startup" msgstr "Sauvegarder et restaurer la liste de lecture à l'extinction/démarrage" msgid "Save playlist periodically [min]:" msgstr "Sauvegarder périodiquement la liste de lecture [min] :" msgid "Album mode is the default when adding entire records" msgstr "Le mode Album est le mode par défaut lors de l'ajout" msgid "Always show the tab bar" msgstr "Toujours afficher la barre des onglets" msgid "Show close button in tab" msgstr "Afficher un bouton de fermeture dans les onglets" # Trop merci quoi ! msgid "When shuffling, records added in Album mode are played in order" msgstr "Lorsque l'ordre de lecture est 'au hasard' les albums ajouté en mode " "'Album' sont joués dans l'ordre" msgid "Enable statusbar" msgstr "Activer la barre de status" msgid "Enable statusbar in playlist" msgstr "Activer la barre de status dans la liste de lecture" msgid "Show soundfile size in statusbar" msgstr "Afficher la taille du fichier dans la barre de status" msgid "Show RVA values" msgstr "Afficher les valeurs RVA" msgid "Show track lengths" msgstr "Afficher les durées des pistes" msgid "Show active track name in bold" msgstr "Afficher la piste active en gras" msgid "Automatically roll to active track" msgstr "Bouger le curseur automatiquement vers la piste active" msgid "Enable rules hint" msgstr "Activer les indications sur les règles" msgid "Playlist column order" msgstr "Ordre des colonnes de la liste de lecture" msgid "" "Drag and drop entries in the list below \n" "to set the column order in the Playlist." msgstr "" "Glissez et déposez les éléments de la liste en dessous\n" "pour régler l'ordre des colonnes dans la liste de lecture." msgid "Column" msgstr "Colonne" msgid "Track titles" msgstr "Titre de la piste" msgid "RVA values" msgstr "Valeurs RVA" msgid "Track lengths" msgstr "Durée de la piste" msgid "Hide comment pane" msgstr "Cacher le panneau de commentaire" msgid "Hide the Music Store comment pane" msgstr "Cacher la discothèque dans le panneau de commentaire" msgid "Enable toolbar" msgstr "Activer la barre d'outils" msgid "Enable toolbar in Music Store" msgstr "Activer la barre d'outils dans la discothèque" msgid "Enable statusbar in Music Store" msgstr "Activer la barre de status dans la discothèque" msgid "Expand Stores on startup" msgstr "Dérouler les discothèques au démarrage" msgid "Enable tree node icons" msgstr "Afficher les icônes des noeuds des arbres" msgid "Enable Music Store tree node icons" msgstr "Afficher les icônes des noeuds dans l'arbre de la discothèque" msgid "Ask for confirmation when removing items" msgstr "Demander confirmation lors de la suppression d'éléments" msgid "Paths to Music Store databases" msgstr "Chemins de fichiers vers les base de données de la discothèque" msgid "Path" msgstr "Chemin" msgid "Access" msgstr "Accès" msgid "Refresh" msgstr "Rafraîchir" msgid "DSP" msgstr "DSP" msgid "LADSPA plugin processing" msgstr "" msgid "Pre Fader (before Volume & Balance)" msgstr "Pre Fader (avant le Volume & l'Équilibrage" msgid "Post Fader (after Volume & Balance)" msgstr "Post Fader (après le Volume & l'Équilibrage" msgid "" "Aqualung is compiled without LADSPA plugin support.\n" "See the About box and the documentation for details." msgstr "" "Cet Aqualung a été généré sans le support de LADSPA.\n" "Consultez la fenêtre 'A propos' et la documentation pour plus de détails." msgid "Sample Rate Converter type" msgstr "Type du Convertisseur du Taux d'Échantillonage" msgid "" "Aqualung is compiled without Sample Rate Converter support.\n" "See the About box and the documentation for details." msgstr "" "Cet Aqualung a été généré sans le support de la Conversion du Taux d'Échantillonage.\n" "Consultez la fenêtre 'A propos' et la documentation pour plus de détails." msgid "Playback RVA" msgstr "" msgid "Enable playback RVA" msgstr "Activer le playback RVA" msgid "Listening environment:" msgstr "Environnement d'écoute :" msgid "Audiophile" msgstr "Audiophile" msgid "Living room" msgstr "Salon" msgid "Office" msgstr "Bureau" msgid "Noisy workshop" msgstr "Magasin bruyant" msgid "Reference volume [dBFS] :" msgstr "Volume de référence [dBFS] :" msgid "Steepness [dB/dB] :" msgstr "Pente [dB/dB] :" msgid "RVA for Unmeasured Files [dB] :" msgstr "RVA pour les Fichiers non Mesurés [dB] :" msgid "Apply averaged RVA to tracks of the same record" msgstr "Appliquer une moyenne RVA sur les piste du même album" msgid "Drop statistical aberrations based on" msgstr "Ne pas prendre en compte les aberrations statistiques basées sur" #, no-c-format msgid "% of standard deviation" msgstr "% de la variance" msgid "Linear threshold [dB]" msgstr "Seuil linéaire [dB]" msgid "Linear threshold [dB] :" msgstr "Seuil linéaire [dB] :" #, no-c-format msgid "% of standard deviation :" msgstr "% de la variance :" msgid "ReplayGain tag to use (with fallback to the other): " msgstr "Étiquette ReplayGain à utiliser (se replier sur les autres au besoin) : " msgid "Replaygain_track_gain" msgstr "" msgid "Replaygain_album_gain" msgstr "" msgid "Adding files to Playlist" msgstr "Ajout en cours de fichiers dans la liste de lecture" msgid "" "Use basename only instead of full path\n" "if no metadata is available." msgstr "" "Utiliser le nom du fichier seulement à la place du chemin entier\n" "en l'absence de méta-données." msgid "Metadata editor (File info dialog)" msgstr "Éditeur de méta-données (Fenêtre d'information sur du fichier)" msgid "" "When adding new frames, try to set their contents\n" "from another tag's equivalent frame." msgstr "" "Lors de l'ajout de nouveaux cadres, essayer d'initialiser leurs contenus\n" "avec le cadre d'une étiquette équivalente." msgid "Batch update & encode (mass tagger, CD ripper, file export)" msgstr "Mise à jour & encodage scripté (étiquettage de masse, encodage de CD, export de fichier)" msgid "Tags to add when creating or updating MPEG audio files:" msgstr "Étiquettes à ajouter lors de la création ou la mise à jour de fichiers MPEG audio :" msgid "" "Note: pre-existing tags will be updated even though they\n" "might not be checked here." msgstr "" msgid "CD Audio" msgstr "" msgid "CD drive speed:" msgstr "Vitesse du lecteur CD-ROM :" msgid "\tMaximum number of retries:" msgstr "\tNombre maximale de retentatives :" msgid "Force TOC re-read on every drive scan" msgstr "Forcer la relecture du sommaire à chaque analyse du lecteur" msgid "Automatically add CDs to Playlist" msgstr "Ajouter automatiquement les CD-ROMs dans la liste de lecture" msgid "Automatically remove CDs from Playlist" msgstr "Enlever automatiquement les CD-ROMs de la liste de lecture" msgid "CDDB server:" msgstr "Serveur CDDB :" msgid "Connection timeout [sec]:" msgstr "Délai d'attente maximal pour la connexion [sec] :" msgid "Email address for submission:" msgstr "Courriel pour la proposition :" msgid "Local CDDB directory:" msgstr "Dossier CDDB local :" msgid "Use the local database only" msgstr "Uniquement utiliser la base de données locale" msgid "Protocol for querying (direct connection only):" msgstr "Protocole pour les requêtes (connexion directe seulement) :" msgid "CDDBP (port 888)" msgstr "" msgid "HTTP (port 80)" msgstr "" msgid "Internet" msgstr "" msgid "Direct connection to the Internet" msgstr "Connexion directe vers Internet" msgid "Connect via HTTP proxy" msgstr "Connexion via un serveur HTTP mandataire (proxy)" msgid "Proxy settings" msgstr "Préférences du serveur mandataire" msgid "Proxy host:" msgstr "Serveur mandataire :" msgid "Port:" msgstr "Port :" msgid "No proxy for:" msgstr "Ne pas passer par le serveur mandataire pour :" msgid "Timeout for socket I/O:" msgstr "Délai avant de considérer une connexion comme perdue :" msgid "seconds" msgstr "secondes" msgid "Appearance" msgstr "Apparence" msgid "Override skin settings" msgstr "Surcharger les préférences du thème" msgid "Fonts" msgstr "Polices" msgid "Playlist: " msgstr "Liste de lecture : " msgid "Music Store: " msgstr "Discothèque : " msgid "Big timer: " msgstr "Grande minuterie : " msgid "Small timers: " msgstr "Petites minuteries : " msgid "Song title: " msgstr "Titre de la chanson : " msgid "Song info: " msgstr "Informations sur la chanson : " msgid "Statusbar: " msgstr "Barre de status : " msgid "Colors" msgstr "Couleurs" msgid "Song in playlist: " msgstr "Chanson dans la liste de lecture : " msgid "Active song in playlist: " msgstr "Chanson active dans la liste de lecture : " msgid "Error in title format string" msgstr "Erreur dans la chaîne de caractères de formatage du titre" msgid "(Untitled)" msgstr "(Sans titre)" #, c-format msgid " (%d/%d)" msgstr "" msgid "Select files" msgstr "Sélectioner des fichiers" msgid "Select directory" msgstr "Sélectioner des dossiers" msgid "Add URL" msgstr "Ajouter une URL" msgid "URL:" msgstr "URL :" msgid "Please specify the file to save the playlist to." msgstr "Veuillez spécifier vers quel fichier enregistrer la liste de lecture." msgid "Please specify the file to load the playlist from." msgstr "Veuillez spécifier depuis quel fichier charger la liste de lecture." msgid "" "Playback RVA is currently disabled.\n" "Do you want to enable it now?" msgstr "" "Le playback RVA est actuellement désactivé.\n" "Souhaitez vous l'activer maintenant ?" msgid "counting..." msgstr "en train de compter..." msgid "track" msgstr "piste" msgid "tracks" msgstr "pistes" msgid "Rename playlist" msgstr "Renommer la liste de lecture" msgid "Name:" msgstr "Nom :" msgid "New tab" msgstr "Nouvel onglet" msgid "Close tab" msgstr "Fermet l'onglet" msgid "Undo close tab" msgstr "Annuler la fermeture de l'onglet" msgid "Close other tabs" msgstr "Fermer les autres onglets" msgid " Selected: " msgstr " Sélectioné: " msgid "Total: " msgstr "Total : " msgid "Add files" msgstr "Ajouter des fichiers" msgid "" "Add files to playlist\n" "(Press right mouse button for menu)" msgstr "" "Ajouter des fichiers dans la liste de lecture\n" "(Faites un clic droit pour le menu)" msgid "Select all" msgstr "Sélectionner tout" msgid "" "Select all songs in playlist\n" "(Press right mouse button for menu)" msgstr "" "Sélectioner toutes les chansons de la liste de lecture\n" "(Faites un clic droit pour le menu)" msgid "Remove selected" msgstr "Retirer la sélection" msgid "" "Remove selected songs from playlist\n" "(Press right mouse button for menu)" msgstr "" "Enlever les chansons sélectionnées de la liste de lecture\n" "(Faites un clic droit pour le menu)" msgid "Add directory" msgstr "Ajouter un dossier" msgid "Select none" msgstr "Annuler la sélection" msgid "Invert selection" msgstr "Inverser la sélection" msgid "Remove all" msgstr "Tout retirer" msgid "Remove dead" msgstr "Enlever les périmés" msgid "Cut selected" msgstr "Coupez la sélection" msgid "Save playlist" msgstr "Sauvegarder la liste de lecture" msgid "Save all playlists" msgstr "Sauvegarder toutes les listes de lecture" msgid "Load playlist in new tab" msgstr "Charger une liste de lecture dans un nouvel onglet" msgid "Load playlist" msgstr "Charger une liste de lecture" msgid "Enqueue playlist" msgstr "Rajouter une liste de lecture" msgid "Send to iFP device" msgstr "Envoyer vers le périphérique iFP" msgid "Calculate RVA" msgstr "Calculer le RVA" msgid "Separate" msgstr "Séparer" msgid "Average" msgstr "Moyenne" msgid "Reread file metadata" msgstr "Relire les méta-données" msgid "File info..." msgstr "Informations sur le fichier..." msgid "Roll to active song" msgstr "Déplacer le curseur sur la chanson active" msgid "Stop adding files" msgstr "Arrêter l'ajout des fichiers" msgid "Files selected for removal" msgstr "Fichiers sélectionnés pour la suppression" msgid "Remove files" msgstr "Retirer les fichiers" msgid "" "The selected files will be deleted from the filesystem. No recovery will be " "possible after this operation.\n" "\n" "Do you want to proceed?" msgstr "" "Les fichiers sélectionnés vont être définitivement supprimés. Vous ne " "pourrez pas annuler cette opération.\n" "\n" "Voulez vous continuer ?" #, c-format msgid "Unable to remove %d file." msgstr "Impossible de supprimer %d fichier." #, c-format msgid "Unable to remove %d files." msgstr "Impossible de supprimer %d fichiers." msgid "LADSPA patch builder" msgstr "Configuration LADSPA" msgid "Available plugins" msgstr "Modules disponibles" msgid "ID" msgstr "ID" msgid "Category" msgstr "Catégorie" msgid "Inputs" msgstr "Entrées" msgid "Outputs" msgstr "Sorties" msgid "Running plugins" msgstr "Modules activés" msgid "_Configure" msgstr "_Configurer" msgid "Enable all plugins" msgstr "Activer tous les modules" msgid "Disable all plugins" msgstr "Désactiver tous les modules" msgid "Invert current state" msgstr "Inverser l'état courant" msgid "Clear list" msgstr "Vider la liste" msgid "Untitled" msgstr "Sans titre" msgid "JACK Port Setup" msgstr "Configuration des Ports JACK" msgid "Rescan" msgstr "Rebalayer" msgid "Available connections" msgstr "Connexions disponibles" msgid "Clear connections" msgstr "Effacer les connexions" msgid " out L" msgstr " sortie G" msgid " out R" msgstr " sortie D" msgid "Search the Music Store" msgstr "Rechercher dans la Discothèque" msgid "Key: " msgstr "Clef : " msgid "Case sensitive" msgstr "Sensible à la casse" msgid "Exact matches only" msgstr "Correspondances exactes seulement" msgid "Select first and close window" msgstr "Sélectioner le premier et fermer la fenêtre" msgid "Search in:" msgstr "Rechercher dans : " msgid "Artist names" msgstr "Noms de l'Artiste" msgid "Record titles" msgstr "Titres de l'Album" msgid "Comments" msgstr "Commentaires" msgid "Search" msgstr "Rechercher" msgid "Search the Playlist" msgstr "Rechercher dans la liste de lecture" msgid "Available skins" msgstr "Thèmes disponibles" msgid "Drive info" msgstr "Informations sur le lecteur" msgid "Device path:" msgstr "Chemin du périphérique :" msgid "Vendor:" msgstr "Vendeur :" msgid "Revision:" msgstr "Révision :" msgid "" "The information below is reported by the drive, and\n" "may not reflect the actual capabilities of the device." msgstr "" "Les informations ci-dessous sont données par le lecteur, et\n" "ne reflètent pas forcément les véritables capacités du périphérique." msgid "Eject" msgstr "Éjecter" msgid "Close tray" msgstr "Fermer le tiroir" msgid "Disable manual eject" msgstr "Désactiver l'éjection manuelle" msgid "Select juke-box disc" msgstr "Sélectionner le disque juke-box" msgid "Set drive speed" msgstr "Choisir la vitesse du lecteur" msgid "Detect media change" msgstr "Détecter le changement de média" msgid "Read multiple sessions" msgstr "Lire les sessions multiples" msgid "Hard reset device" msgstr "Redémarrer le périphérique" msgid "Reading" msgstr "Lecture en cours" msgid "Play CD Audio" msgstr "Jouer un CD Audio" msgid "Read CD-DA" msgstr "Lire un CD-DA" msgid "Read CD+G" msgstr "Lire un CD+G" msgid "Read CD-R" msgstr "Lire un CD-R" msgid "Read CD-RW" msgstr "Lire un CD-RW" msgid "Read DVD-R" msgstr "Lire un DVD-R" msgid "Read DVD+R" msgstr "Lire un DVD+R" msgid "Read DVD-RW" msgstr "Lire un DVD-RW" msgid "Read DVD+RW" msgstr "Lire un DVD+RW" msgid "Read DVD-RAM" msgstr "Lire un DVD-RAM" msgid "Read DVD-ROM" msgstr "Lire un DVD-ROM" msgid "C2 Error Correction" msgstr "Correction d'erreurs C2" msgid "Read Mode 2 Form 1" msgstr "Mode de Lecture 2 Forme 1" msgid "Read Mode 2 Form 2" msgstr "Mode de Lecture 2 Forme 2" msgid "Read MCN" msgstr "Lire le MCN" msgid "Read ISRC" msgstr "Lier le ISRC" msgid "Writing" msgstr "Écriture en cours" msgid "Write CD-R" msgstr "Écrire un CD-R" msgid "Write CD-RW" msgstr "Écrire un CD-RW" msgid "Write DVD-R" msgstr "Écrire un DVD-R" msgid "Write DVD+R" msgstr "Écrire un DVD+R" msgid "Write DVD-RW" msgstr "Écrire un DVD-RW" msgid "Write DVD+RW" msgstr "Écrire un DVD+RW" msgid "Write DVD-RAM" msgstr "Écrire un DVD-RAM" msgid "Mount Rainier" msgstr "Mont Rainier" msgid "Burn Proof" msgstr "" msgid "Disc info" msgstr "Informations sur le disque" msgid "This CD does not contain CD-Text information." msgstr "Ce CD ne contient pas d'information CD-Text." msgid "drive" msgstr "lecteur" msgid "drives" msgstr "lecteurs" msgid "record" msgstr "album" msgid "records" msgstr "albums" msgid "Add to playlist" msgstr "Ajouter dans la liste de lecture" msgid "Add to playlist (Album mode)" msgstr "Ajouter dans la liste de lecture (mode Album)" msgid "CDDB query for this CD..." msgstr "Requête CDDB pour ce CD..." msgid "Submit CD to CDDB database..." msgstr "Soumettre le CD à la base de données CDDB.." msgid "Rip CD..." msgstr "Encoder le CD..." msgid "Disc info..." msgstr "Informations sur le disque..." msgid "Drive info..." msgstr "Informations sur le lecteur..." msgid "Comments:" msgstr "Commentaires :" msgid "Please select the xml file for this store." msgstr "Veuillez sélectionner le fichier xml pour cette discothèque." msgid "Create empty store" msgstr "Créer une discothèque vide" msgid "Visible name:" msgstr "Nom visible :" msgid "Edit Store" msgstr "Éditer la discothèque" msgid "Use relative paths in store file" msgstr "Utiliser des chemins relatifs dans la discothèque" msgid "Add Artist" msgstr "Ajouter un Artiste" msgid "Name to sort by:" msgstr "Nom par lequel trier :" msgid "Edit Artist" msgstr "Éditer l'artiste" msgid "Please select the audio files for this record." msgstr "Veuillez sélectionner les fichiers audios pour cet album." msgid "Add Record" msgstr "Ajouter un Album" msgid "Auto-create tracks from these files:" msgstr "Créer automatiquement les pistes pour ces fichiers :" msgid "_Add files..." msgstr "_Ajouter des fichiers..." msgid "Edit Record" msgstr "Ëditer l'Album" msgid "Please select the audio file for this track." msgstr "Veuillez sélectionner les fichiers audio pour cette piste." msgid "Add Track" msgstr "Ajouter une Piste" msgid "Edit Track" msgstr "Éditer la Piste" msgid "Duration:" msgstr "Duré :" #, c-format msgid "Unmeasured" msgstr "Non mesuré" msgid "Volume level:" msgstr "Niveau du volume :" msgid "Use manual RVA value [dB]" msgstr "Utiliser une valeur manuel pour le RVA [dB]" #, c-format msgid "Really remove \"%s\" from the Music Store?" msgstr "Retirer vraiment \"%s\" de la discothèque ?" msgid "Stop adding songs" msgstr "Arrêter l'ajout de chansons" #, c-format msgid "" "The store '%s' already exists.\n" "Add it on the Settings/Music Store tab." msgstr "" "La discothèque '%s' existe déjà.\n" "Ajouter la sur l'onglet Préférences/Discothèque." #, c-format msgid "Really remove store \"%s\" from the Music Store?" msgstr "Retirer vraiment la discothèque \"%s\" des Discothèques ?" msgid "Remove Store" msgstr "Retirer la discothèque" msgid "Do you want to save the store before removing?" msgstr "Voulez vous sauvegarder la discothèque avant de l'enlever ?" msgid "Remove Artist" msgstr "Retirer l'Artiste" msgid "Remove Record" msgstr "Retirer l'Album" msgid "Remove Track" msgstr "Retirer la Piste" msgid "Update file metadata" msgstr "Mettre à jour les méta-données" msgid "Track name" msgstr "Nom de la piste" msgid "Track comment" msgstr "Commentaire de la piste" msgid "Track number" msgstr "Numéro de la piste" msgid "Failed to set metadata for the following files:" msgstr "Impossible de mettre les méta-données pour les fichiers suivants :" msgid "Filename" msgstr "Nom du fichier" msgid "Reason" msgstr "Raison" msgid "(no comment)" msgstr "(pas de commentaire)" msgid "artist" msgstr "artiste" msgid "artists" msgstr "artistes" #, c-format msgid "" "File \"%s\" does not exist or your write permission has been withdrawn. " "Check if the partition containing the store file has been unmounted." msgstr "" "Le fichier \"%s\" n'existe pas ou vos droits d'écriture ont été retirés. " "Vérifier si la paritition contenant la discothèque n'a pas été éjectée." msgid "Build / Update store from filesystem..." msgstr "Générer / Mettre à jour depuis le système de fichiers..." msgid "Edit store..." msgstr "Éditer la discothèque..." msgid "Export store..." msgstr "Expoter la discothèque..." msgid "Save store" msgstr "Sauvegarder la discothèque" msgid "Remove store" msgstr "Retirer la discothèque" msgid "Add new artist to this store..." msgstr "Ajouter un nouvel artiste dans cette discothèque..." msgid "Calculate volume (recursive)" msgstr "Calculer le volume (récursif)" msgid "Unmeasured tracks only" msgstr "Pistes non mesurées seulement" msgid "All tracks" msgstr "Toutes les pistes" msgid "Batch-update file metadata..." msgstr "Mise à jour scripté des méta-données..." msgid "Add new artist..." msgstr "Ajouter un nouvel artiste..." msgid "Edit artist..." msgstr "Éditer l'artiste..." msgid "Export artist..." msgstr "Exporter l'artiste..." msgid "Remove artist" msgstr "Enlever l'artiste" msgid "Add new record to this artist..." msgstr "Ajouter de nouveaux album à cet artiste..." msgid "Add new record..." msgstr "Ajouter un nouvel album..." msgid "Edit record..." msgstr "Éditer l'album..." msgid "Export record..." msgstr "Expoter l'album..." msgid "Remove record" msgstr "Enlever l'album" msgid "Add new track to this record..." msgstr "Ajouter de nouvelles pistes à cet album..." msgid "CDDB query for this record..." msgstr "Requête CDDB pour cet album..." msgid "Submit record to CDDB database..." msgstr "Soumettre cet album à la base de données CDDB..." msgid "Add new track..." msgstr "Ajouter une nouvelle piste..." msgid "Edit track..." msgstr "Éditer la piste..." msgid "Export track..." msgstr "Exporter la piste..." msgid "Remove track" msgstr "Retirer la piste..." msgid "Calculate volume" msgstr "Calculer le volume" msgid "Only if unmeasured" msgstr "Seulement si non-mesuré" msgid "In any case" msgstr "Dans tous les cas" msgid "Update file metadata..." msgstr "Mettre à jour les méta-données..." msgid "Please select the download directory for this podcast." msgstr "Veuillez sélectionner le dossier de téléchargement pour ce podcast." msgid "Subscribe to new feed" msgstr "S'inscrire à un nouveau flux" msgid "Edit feed settings" msgstr "Éditer les préférences du flux" msgid "Podcast URL:" msgstr "URL du Podcast :" msgid "Download directory:" msgstr "Dossier de téléchargement :" msgid "Auto-check interval [hour]:" msgstr "Interval de vérification automatique [heures] :" msgid "" "Automatic update has been disabled for all feeds\n" "in the Podcasts store popup menu." msgstr "" "Les mises à jours automatiques ont été désactivées pour tous les flux\n" "dans le menu de la discothèque des Podcasts." msgid "Limits" msgstr "Limites" msgid "Maximum number of items:" msgstr "Nombre maximum d'éléments :" msgid "Remove older items [day]:" msgstr "Retirer les anciens éléments [jours] :" msgid "Maximum space to use [MB]:" msgstr "Espace maximal à utiliser [MB] :" msgid "Podcasts" msgstr "Podcasts" msgid "Updating..." msgstr "Mise à jour..." msgid "Delete downloaded items from the filesystem" msgstr "Supprimer les éléments téléchargés depuis le système de fichiers" msgid "Remove feed" msgstr "Retirer le flux" #, c-format msgid "Really remove '%s' from the Music Store?" msgstr "Retirer vraiment '%s' de la Discothèque ?" msgid "Reorder feeds" msgstr "Réordonner les fluxs" msgid "" "Drag and drop entries in the list\n" "to set the feed order in the Music Store." msgstr "" "Glisser et déposer les entrées dans la liste\n" "pour choisir l'ordre des flux dans la Discothèque." #, c-format msgid "Downloading %d/%d (%d%%) ..." msgstr "Téléchargement %d/%d (%d%%) ..." msgid "item" msgstr "élément" msgid "items" msgstr "éléments" msgid "new item" msgstr "nouvel élément" msgid "new items" msgstr "nouveaux éléments" msgid "feed" msgstr "flux" msgid "feeds" msgstr "fluxs" msgid "Export item..." msgstr "Exporter un élément..." msgid "Add all items to playlist" msgstr "Ajouter tous les éléments dans la liste de lecture" msgid "Add all items to playlist (Album mode)" msgstr "Ajouter tous les éléments dans la liste de lecture (mode Album)" msgid "Add new items to playlist" msgstr "Ajouter les nouveaux éléments dans la liste de lecture" msgid "Add new items to playlist (Album mode)" msgstr "Ajouter les nouveaux éléments dans la liste de lecture" msgid "Edit feed" msgstr "Éditer le flux" msgid "Export all items..." msgstr "Expoter tous les éléments..." msgid "Export new items..." msgstr "Exporter les nouveaux éléments..." msgid "Update feed" msgstr "Mettre à jour le flux" msgid "Abort ongoing update" msgstr "Abandonner la mise à jour en cours" msgid "Update all feeds" msgstr "Mettre à jours tous les fluxs" msgid "Automatically update feeds" msgstr "Automatiquement mettre à jour les fluxs" msgid "Unexpected end of string after '?'." msgstr "Fin inattendue de la chaîne de caractères après '?'." msgid "Expected '}' after '{', but end of string found." msgstr "'}' était attendu après '{', mais la fin de la chaîne de caractères " "à été trouvée." #, c-format msgid "Unknown conversion type character found after '%%%%'." msgstr "Caractère de conversion inconnu trouvé après '%%%%'." msgid "Unknown conversion type character found after '?'." msgstr "Caractère de conversion inconnu trouvé après '?'." msgid "day" msgstr "jour" msgid "days" msgstr "jours" msgid "All Files" msgstr "Tout les fichiers" msgid "Extended Title Format Files (*.lua)" msgstr "Fichiers de Format de Titres Formatables (*.lua)" msgid "Music Store Files (*.xml)" msgstr "Fichiers de Discothèques (*.xml)" msgid "Aqualung playlist (*.xml)" msgstr "Liste de lecture (*.xml)" msgid "MP3 Playlist (*.m3u)" msgstr "Liste de lecture MP3 (*.m3u)" msgid "Multimedia Playlist (*.pls)" msgstr "Liste de lecture Multimédia (*.pls)" msgid "All Playlist Files" msgstr "Tous les Types de Liste de Lecture" msgid "All Audio Files" msgstr "Tous les Fichiers Audios" msgid "Sound Files (*.wav, *.aiff, *.au, ...)" msgstr "Fichiers Audio (*.wav, *.aiff, *.au, ...)" msgid "Free Lossless Audio Codec (*.flac)" msgstr "" msgid "MPEG Audio (*.mp3, *.mpa, *.mpega, ...)" msgstr "" msgid "Ogg Vorbis (*.ogg)" msgstr "" msgid "Ogg Speex (*.spx)" msgstr "" msgid "Musepack (*.mpc)" msgstr "" msgid "Monkey's Audio Codec (*.ape)" msgstr "" msgid "Modules (*.xm, *.mod, *.it, *.s3m, ...)" msgstr "" msgid "Compressed modules (*.gz, *.bz2)" msgstr "Modules compressés (*.gz, *.bz2)" msgid "Compressed modules (*.gz)" msgstr "Modules compressés (*.gz)" msgid "Compressed modules (*.bz2)" msgstr "Modules compressés (*.bz2)" msgid "WavPack (*.wv)" msgstr "" msgid "LAVC audio/video files" msgstr "" msgid "Resume" msgstr "Reprendre" msgid "Calculating volume level" msgstr "Calcul du niveau de volume en cours" msgid "Profile: Telephone" msgstr "Profile : Téléphone" msgid "Profile: Thumb" msgstr "Profile : Petite taille" msgid "Profile: Radio" msgstr "Profile : Radio" msgid "Profile: Standard" msgstr "Profile : Standard" msgid "Profile: Xtreme" msgstr "Profile : Extreme" msgid "Profile: Insane" msgstr "Profile : Insensé" msgid "Profile: Braindead" msgstr "Profile : Encéphalogramme plat" msgid "Layer I" msgstr "Couche I" msgid "Layer II" msgstr "Couche II" msgid "Layer III" msgstr "Couche III" msgid "Unrecognized" msgstr "Inconnue" msgid "Single channel" msgstr "Simple canal" msgid "Dual channel" msgstr "Double canal" msgid "Joint stereo" msgstr "Stéréo jointe" msgid "Stereo" msgstr "Stéréo" msgid "Emphasis: none" msgstr "Emphase : aucune" msgid "Emphasis:" msgstr "Emphase :" msgid "Emphasis: reserved" msgstr "Emphase : réservé" msgid "bit signed" msgstr "bit signé" msgid "bit unsigned" msgstr "bit non signé" msgid "bit float" msgstr "bit flottant" msgid "bit double" msgstr "bit double" msgid "encoding" msgstr "encodage" msgid "Compression: Fast" msgstr "Compression : Rapide" msgid "Compression: Normal" msgstr "Compression : Normale" msgid "Compression: High" msgstr "Compression : Élevée" msgid "Compression: Extra High" msgstr "Compression : Très Élevée" msgid "Compression: Insane" msgstr "Compression : Insensé" aqualung-0.9beta11/src/po/hu.po0000644000175000001440000021332211331334210013265 00000000000000# Hungarian translations for aqualung package. # Hungarian messages for aqualung. # Copyright (C) 2004 Tom Szilagyi # This file is distributed under the same license as the aqualung package. # Peter Szilagyi , 2005. # msgid "" msgstr "" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2010-01-13 00:15+0100\n" "PO-Revision-Date: 2010-01-13 00:16+0100\n" "Last-Translator: Peter Szilagyi \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" msgid "About" msgstr "Névjegy" msgid "Build version: " msgstr "Fordítási verzió: " msgid "Homepage:" msgstr "Honlap:" msgid "Authors:" msgstr "Szerzők:" msgid "Core design, engineering & programming:\n" msgstr "Architektúra, tervezés & programozás:\n" msgid "Skin support, look & feel, GUI hacks:\n" msgstr "Skin támogatás, kinézet, jusztírozás:\n" msgid "Programming, GUI engineering:\n" msgstr "Programozás, GUI tervezés:\n" msgid "OpenBSD compatibility, metadata tweaks:\n" msgstr "OpenBSD kompatibilitás, metaadat trükkök\n" msgid "Translators:" msgstr "Fordítók:" msgid "French:\n" msgstr "Francia:\n" msgid "German:\n" msgstr "Német:\n" msgid "Hungarian:\n" msgstr "Magyar:\n" msgid "Italian:\n" msgstr "Olasz:\n" msgid "Japanese:\n" msgstr "Japán:\n" msgid "Russian:\n" msgstr "Orosz:\n" msgid "Swedish:\n" msgstr "Svéd:\n" msgid "Ukrainian:\n" msgstr "Ukrán:\n" msgid "Graphics:" msgstr "Grafika:" msgid "Logo, icons:\n" msgstr "Logo, ikonok:\n" msgid "This Aqualung binary is compiled with:" msgstr "Ez az Aqualung bináris a következő opciókat támogatja:" msgid "Optional features:" msgstr "Opcionális funkciók:" msgid "LADSPA plugin support\n" msgstr "LADSPA effekt támogatás\n" msgid "CDDA (Audio CD) support\n" msgstr "CDDA (Audio CD) támogatás\n" msgid "CDDB support\n" msgstr "CDDB támogatás\n" msgid "Sample Rate Converter support\n" msgstr "Mintavételi frekvencia konverter támogatás\n" msgid "iRiver iFP driver support\n" msgstr "iRiver iFP meghajtó támogatás\n" msgid "Loop playback support\n" msgstr "Ciklikus lejátszás támogatás\n" msgid "Systray support\n" msgstr "Rendszertálca támogatás\n" msgid "Podcast support\n" msgstr "Podcast támogatás\n" msgid "Lua (programmable title formatting) support\n" msgstr "Lua támogatás (programozható címformátum)\n" msgid "Decoding support:" msgstr "Dekódolás támogatása:" msgid "sndfile (WAV, AIFF, etc.)\n" msgstr "sndfile (WAV, AIFF, stb.)\n" msgid "Free Lossless Audio Codec (FLAC)\n" msgstr "Free Lossless Audio Codec (FLAC)\n" msgid "Ogg Vorbis\n" msgstr "Ogg Vorbis\n" msgid "Ogg Speex\n" msgstr "Ogg Speex\n" msgid "MPEG Audio (MPEG 1-2.5 Layer I-III)\n" msgstr "MPEG Audio (MPEG 1-2.5 I-III. Réteg)\n" msgid "MOD Audio (MOD, S3M, XM, IT, etc.)\n" msgstr "MOD Audio (MOD, S3M, XM, IT, stb.)\n" msgid "Musepack\n" msgstr "Musepack\n" msgid "Monkey's Audio Codec\n" msgstr "Monkey's Audio Codec\n" msgid "WavPack\n" msgstr "WavPack\n" msgid "LAVC (AC3, AAC, WavPack, WMA, etc.)\n" msgstr "LAVC (AC3, AAC, WavPack, WMA, stb.)\n" msgid "Encoding support:" msgstr "Kódolás támogatása:" msgid "sndfile (WAV)\n" msgstr "sndfile (WAV)\n" msgid "LAME (MP3)\n" msgstr "LAME (MP3)\n" msgid "Output driver support:" msgstr "Kimeneti meghajtók:" msgid "sndio Audio\n" msgstr "sndio Audio\n" msgid "OSS Audio\n" msgstr "OSS Audio\n" msgid "ALSA Audio\n" msgstr "ALSA Audio\n" msgid "JACK Audio Server\n" msgstr "JACK Audio Szerver\n" msgid "PulseAudio\n" msgstr "PulseAudio\n" msgid "Win32 Sound API\n" msgstr "Win32 Sound API\n" msgid "" "This program is free software; you can redistribute it and/or modify it " "under the terms of the GNU General Public License as published by the Free " "Software Foundation; either version 2 of the License, or (at your option) " "any later version.\n" "\n" "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.\n" "\n" "You should have received a copy of the GNU General Public License along with " "this program; if not, write to the Free Software Foundation, Inc., 675 Mass " "Ave, Cambridge, MA 02139, USA." msgstr "" "Ez egy szabad szoftver; terjeszthető illetve módosítható a Szabad Szoftver " "Alapítvány által kiadott GNU Általános Közreadási Feltételek (GPL) második " "(vagy bármely későbbi) változatában foglaltak alapján.\n" "\n" "A programot abban a reményben adjuk közre, hogy hasznos lesz, de nem " "vállalunk SEMMIFÉLE GARANCIÁT; beleértve az ELADHATÓSÁGRA vagy egy BIZONYOS " "FELADAT ELVÉGZÉSÉRE vonatkozó származtatott garanciát is. További részletek " "a GNU GPL dokumentumában.\n" "\n" "A programhoz a GNU GPL egy példánya is jár; ha nem kaptad meg, írj a Szabad " "Szoftver Alapítvány címére: Free Software Foundation, Inc., 675 Mass Ave, " "Cambridge, MA 02139, USA." msgid "Enabled" msgstr "Érvényes" msgid "Source" msgstr "Forrás" msgid "CDDB" msgstr "CDDB" msgid "CDDB (not available)" msgstr "CDDB (nem elérhető)" msgid "Metadata" msgstr "Metaadatok" msgid "Filesystem" msgstr "Fájlrendszer" msgid "Capitalization" msgstr "Kis/nagybetű beállítása" msgid "Capitalize: " msgstr "Nagy kezdőbetű:" msgid "All words" msgstr "Minden szónál" msgid "First word only" msgstr "Csak az első szónál" msgid "Force case: " msgstr "Alak megőrzése: " msgid "Force other letters to lowercase" msgstr "A többi legyen kisbetű" msgid "Regular expression" msgstr "Reguláris kifejezés" msgid "Regexp:" msgstr "Kifejezés:" msgid "Replace:" msgstr "Csere:" msgid "Predefined transformations" msgstr "Előre definiált transzformációk" msgid "Remove file extension" msgstr "Kiterjesztés levágása" msgid "Remove leading number" msgstr "Kezdő számjegyek levágása" msgid "Convert underscore to space" msgstr "Aláhúzás szóközzé alakítása" msgid "Trim leading, tailing and duplicate spaces" msgstr "Kezdő, végző és többszörös szóközök eltávolítása" msgid "Regexp matches empty string" msgstr "A kifejezés fedi az üres karakterláncot" msgid "Please select the root directory." msgstr "Válaszd ki a gyökérkönyvtárat." msgid "Select build type" msgstr "Felépítés típusának kiválasztása" msgid "Directory driven" msgstr "Könyvtár alapú" msgid "" "Follows the directory structure to identify the artists and\n" "records. The files are added on a record basis." msgstr "" "A könyvtárstruktúrát követve határozza meg az előadókat\n" "és albumokat. A fájlok hozzáadása albumonként történik." msgid "Independent" msgstr "Független" msgid "" "Recursive search from the root directory for audio files.\n" "The files are processed independently, so only metadata\n" "and filename transformation are available." msgstr "" "Hangfájlok rekurzív keresése a gyökérkönyvtárból kiindulva.\n" "A fájlok feldolgozása külön történik, ezért csak metaadatokra\n" "és fájlnév transzformációra támaszkodik." msgid "Load settings from Music Store file" msgstr "Beállítások betöltése a Zenetár fájlból" msgid "Build/Update store" msgstr "Tároló felépítése/aktualizálása" msgid "General" msgstr "Általános" msgid "Directory structure" msgstr "Könyvtár struktúra" msgid "Root path:" msgstr "Gyökérkönyvtár:" msgid "_Browse..." msgstr "_Tallózás..." msgid "Structure:" msgstr "Struktúra:" msgid "root / record / track" msgstr "gyökér / album / szám" msgid "root / artist / record / track" msgstr "gyökér / előadó / album / szám" msgid "root / artist / artist / record / track" msgstr "gyökér / előadó / előadó / album / szám" msgid "root / artist / artist / artist / record / track" msgstr "gyökér / előadó / előadó / előadó / album / szám" msgid "Exclude files matching wildcard" msgstr "Mintára illeszkedő fájlok kihagyása" msgid "Include only files matching wildcard" msgstr "Csak a mintára illeszkedő fájlok vizsgálata" msgid "Reread data for existing tracks" msgstr "Létező számok adatainak újraolvasása" msgid "Remove non-existing files from store" msgstr "Nem létező fájlok eltávolítása a tárolóból" msgid "Artist" msgstr "Szerző" msgid "Sort artists by" msgstr "Előadók rendezése a következő szerint" msgid "Artist name" msgstr "Előadó neve" msgid "Artist name (lowercase)" msgstr "Előadó neve (kisbetűvel)" msgid "Directory name" msgstr "Könyvtár neve" msgid "Directory name (lowercase)" msgstr "Könyvtár neve (kisbetűvel)" msgid "Record" msgstr "Album" msgid "Sort records by" msgstr "Albumok rendezése a következő szerint" msgid "Record name" msgstr "Album címe" msgid "Record name (lowercase)" msgstr "Album címe (kisbetűvel)" msgid "Year" msgstr "Év" msgid "Add year to the comments of new records" msgstr "Év hozzáadása az újonnan felvett albumok kommentjéhez" msgid "Track" msgstr "Szám" msgid "Import Replaygain tag as manual RVA" msgstr "Replaygain tag importálása rögzített RVA-ként" msgid "Import Comment tag" msgstr "Komment tag importálása" msgid "Sandbox" msgstr "Homokozó" msgid "Filename:" msgstr "Fájlnév:" msgid "Test" msgstr "Teszt" msgid "Building store from filesystem" msgstr "Tároló felépítése fájlrendszerről" msgid "Processing:" msgstr "Feldolgozás:" msgid "Action:" msgstr "Művelet:" msgid "Abort" msgstr "Megszakítás" msgid "Unknown Artist" msgstr "Ismeretlen előadó" msgid "Unknown Record" msgstr "Ismeretlen album" msgid "Scanning files" msgstr "Fájlok vizsgálata" msgid "Processing metadata" msgstr "Metaadatok olvasása" msgid "CDDB lookup" msgstr "CDDB lekérdezés" msgid "Name transformation" msgstr "Név transzformáció" msgid "Reading file" msgstr "Fájl olvasása" msgid "Removing non-existing files" msgstr "Nem létező fájlok törlése" msgid "Unknown disc" msgstr "Ismeretlen lemez" msgid "No disc" msgstr "Nincs lemez" msgid "CDDB query" msgstr "CDDB lekérdezés" msgid "Retrieving matches from server..." msgstr "Találatok letöltése a szerverről..." msgid "Connecting to CDDB server..." msgstr "Kapcsolódás a CDDB szerverhez..." msgid "Error" msgstr "Hiba" msgid "An error occurred while attempting to connect to the CDDB server." msgstr "Hiba történt a CDDB szerverhez való kapcsolódás közben." msgid "Warning" msgstr "Figyelmeztetés" msgid "No matching record found." msgstr "Az album nem található az adatbázisban." msgid "Import as Sort Key" msgstr "Importálás kulcsként" msgid "Import as Title" msgstr "Importálás címként" msgid "Import as Year" msgstr "Importálás évként" msgid "" "Artist appears to be in all lowercase.\n" "Do you want to proceed?" msgstr "" "Az előadó csupa kisbetűvel szerepel.\n" "Akarod folytatni?" msgid "" "Artist appears to be in all uppercase.\n" "Do you want to proceed?" msgstr "" "Az előadó csupa nagybetűvel szerepel.\n" "Akarod folytatni?" msgid "" "Title appears to be in all lowercase.\n" "Do you want to proceed?" msgstr "" "A cím csupa kisbetűvel szerepel.\n" "Akarod folytatni?" msgid "" "Title appears to be in all uppercase.\n" "Do you want to proceed?" msgstr "" "A cím csupa nagybetűvel szerepel.\n" "Akarod folytatni?" msgid "" "It is very likely that the year is wrong.\n" "Do you want to proceed?" msgstr "" "Nagyon valószínű, hogy az év hibás.\n" "Akarod folytatni?" msgid "The email address provided for submission is invalid." msgstr "A feltöltéshez megadott email cím érvénytelen." msgid "An error occurred while submitting the record to the CDDB server." msgstr "Hiba történt a lemez CDDB szerverhez való küldése közben." msgid "Correct existing record" msgstr "Meglévő album módosítása" msgid "Submit new record" msgstr "Új album feltöltése" msgid "Matches:" msgstr "Találatok:" msgid "Artist:" msgstr "Előadó:" msgid "Title:" msgstr "Cím:" msgid "Year:" msgstr "Év:" msgid "Category:" msgstr "Kategória:" msgid "(choose a category)" msgstr "(válassz egy kategóriát)" msgid "Genre:" msgstr "Műfaj:" msgid "Extended data:" msgstr "Egyéb adat:" msgid "Import as Artist" msgstr "Importálás előadóként" msgid "Add to Comments" msgstr "Hozzáadás a kommentekhez" msgid "Tracks" msgstr "Számok" msgid "You have to provide an email address for CDDB submission." msgstr "Meg kell adni egy email címet a feltöltéshez." msgid "Please select the directory for ripped files." msgstr "Válassz ki egy könyvtárat a rippelt fájloknak." msgid "(none)" msgstr "(nincs)" msgid "fast" msgstr "gyors" msgid "best" msgstr "legjobb" msgid "Compression level:" msgstr "Tömörítés szintje:" msgid "Bitrate [kbps]:" msgstr "Bitráta [kbps]:" msgid "Artist/Album already existing, not empty" msgstr "Az előadó vagy album már létezik, és nem üres" msgid "" "\n" "The Music Store you selected has a matching Artist and Album, already " "containing some tracks. If you press OK, these tracks will be removed. The " "files themselves will be left intact, but they will be removed from the " "destination Music Store. Press Cancel to get back to change the Artist/Album " "or the destination Music Store." msgstr "" "\n" "A kiválasztott tárolóban már van ilyen előadó és album, amely néhány számot " "is tartalmaz. Az OK gombot megnyomva ezek a számok eltűnnek a tárolóból. Ez " "maguk a fájlokat nem érinti, csak a célként megjelölt tárolóból törlődnek. " "Ha inkább szeretnél visszatérni a előadó, album vagy zenetár módosításához, " "válaszd a Mégse gombot." msgid "Rip CD" msgstr "CD rippelés" msgid "Album:" msgstr "Lemez:" msgid "Rip" msgstr "Rippelés" msgid "No." msgstr "No." msgid "Title" msgstr "Cím" msgid "Select" msgstr "Kiválasztás" msgid "All" msgstr "Mind" msgid "None" msgstr "Egyik sem" msgid "Output" msgstr "Kimenet" msgid "Destination" msgstr "Cél" msgid "Target directory for ripped files" msgstr "Válassz egy könyvtárat a rippelt fájloknak" msgid "Add to Music Store" msgstr "Hozzáadás a Zenetárhoz" msgid "Format" msgstr "Formátum" msgid "File format:" msgstr "Fájl formátum:" msgid "VBR encoding" msgstr "VBR kódolás" msgid "Tag files with metadata" msgstr "Fájlok taggelése metaadatokkal" msgid "Paranoia" msgstr "Paranoia" msgid "Paranoia error correction" msgstr "Paranoia hibajavítás" msgid "Perform overlapped reads" msgstr "Átlapolt olvasások végzése" msgid "Verify data integrity" msgstr "Adat integritás ellenőrzése" msgid "Unlimited retry on failed reads (never skip)" msgstr "" "Meghiúsult olvasások esetén tetszőleges számú újraolvasás (soha nem ugrik)" msgid "Maximum number of retries:" msgstr "Újrapróbálások maximális száma:" msgid "" "\n" "Destination directory is not read-write accessible!" msgstr "" "\n" "A célkönyvtár nem írható-olvasható!" msgid "Total" msgstr "Összesen" msgid "(audio only)" msgstr "(csak audio)" msgid "Ripping CD tracks" msgstr "Számok rippelése" msgid "Begin" msgstr "Kezdet" msgid "Length" msgstr "Hossz" msgid "Progress" msgstr "Feldolgozás" msgid "Close window when complete" msgstr "Ablak bezárása, ha kész" msgid "Close" msgstr "Bezárás" msgid "Unknown Album" msgstr "Ismeretlen lemez" msgid "Unknown Track" msgstr "Ismeretlen szám" msgid "Please select the directory for exported files." msgstr "Válassz ki egy könyvtárat az exportált fájloknak." msgid "Copy" msgstr "Másolás" msgid "Help" msgstr "Súgó" #, c-format msgid "" "\n" "The template string you enter here will be used to construct the filename of " "the exported files. The Artist, Record and Track names are denoted by %%%%a, " "%%%%r and %%%%t. The track number and format-dependent file extension are " "denoted by %%%%n and %%%%x, respectively. The flag %%%%i gives an identifier " "which is unique within an export session." msgstr "" "\n" "Az alábbi sablon az exportált fájlok nevét határozza meg. Az előadó, lemez " "és szám címeket %%%%a, %%%%r és %%%%t jelöli. A track számát és a " "formátumtól függő kiterjesztést %%%%n és %%%%x adja meg. Az %%%%i kapcsoló " "az export folyamaton belül egyedi azonosítót eredményez." msgid "Export files" msgstr "Fájlok exportálása" msgid "Location and filename" msgstr "Hely és fájlnév" msgid "Target directory:" msgstr "Célkönyvtár:" msgid "Create subdirectories for artists" msgstr "Alkönyvtár létrehozása előadónként" msgid "Create subdirectories for albums" msgstr "Alkönyvtár létrehozása lemezenként" msgid "" "Subdirectory name\n" "length limit:" msgstr "" "Alkönyvtár név\n" "maximális hossza:" msgid "Filename template:" msgstr "Fájlnév sablon:" msgid "Filter" msgstr "Szűrő" msgid "Do not reencode files already being in the target format" msgstr "A célformátumban lévő fájlokat ne kódolja újra" msgid "" "Do not reencode files\n" "matching wildcard:" msgstr "" "Mintára illeszkedő\n" "fájlok kihagyása" msgid "Error in format string" msgstr "Hiba a formátum sablonban" msgid "Exporting files" msgstr "Fájlok exportálása" msgid "Source file:" msgstr "Forrás fájl:" msgid "Target file:" msgstr "Célfájl:" msgid "Progress:" msgstr "Feldolgozás:" msgid "*File info" msgstr "*Fájl infó" msgid "File info" msgstr "Fájl infó" msgid "There are unsaved changes to the file metadata." msgstr "A fájl nem mentett metaadat változtatásokat tartalmaz." msgid "Save and close" msgstr "Mentés és bezárás" msgid "Discard changes" msgstr "Változások eldobása" msgid "Do not close" msgstr "Ne zárja be" #, c-format msgid "" "Conversion error in field %s:\n" "'%s' does not conform to format '%s'!" msgstr "" "Konverziós hiba a következő mezőben: %s\n" "'%s' nem felel meg a(z) '%s' formátumnak." msgid "" "Attached Picture frame with no image set!\n" "Please set an image or remove the frame." msgstr "" "Az Attached Picture keretből hiányzik a kép.\n" "Adj meg egyet, vagy töröld a keretet." #, c-format msgid "" "Failed to write metadata to file.\n" "Reason: %s" msgstr "" "A fájlban nem sikerült beállítani a metaadatokat.\n" "A hiba oka: %s" #, c-format msgid "" "Error converting field %s to Year:\n" "'%s' is not an integer number!" msgstr "" "A(z) '%s' mező nem konvertálható évre:\n" "'%s' nem egész szám." msgid "Please specify the file to save the image to." msgstr "Add meg az elmentendő képfájlt." msgid "(no image)" msgstr "(nincs kép)" msgid "(error loading image)" msgstr "(hiba a kép betöltése közben)" msgid "Please specify the file to load the image from." msgstr "Add meg a betöltendő képfájlt." #, c-format msgid "" "Could not load image from:\n" "%s" msgstr "" "Az alábbi helyről nem sikerült képet betölteni:\n" "\"%s\"" #, c-format msgid "MIME type: %s" msgstr "MIME típus: %s" msgid "Picture type:" msgstr "Kép típusa:" msgid "Description:" msgstr "Leírás:" msgid "(no description)" msgstr "(nincs leírás)" msgid "Change" msgstr "Csere" msgid "Save" msgstr "Mentés" msgid "Import as Record" msgstr "Importálás albumként" msgid "Import as Track No." msgstr "Importálás track számaként" msgid "Import as RVA" msgstr "Importálás RVA-ként" msgid "Add" msgstr "Hozzáadás" msgid "field:" msgstr "mező:" msgid "tag:" msgstr "tag:" msgid "Audio CD" msgstr "Audio CD" msgid "Track:" msgstr "Szám:" msgid "File:" msgstr "Fájl:" msgid "Audio data" msgstr "Audio jellemzők" msgid "Format:" msgstr "Formátum:" msgid "Length:" msgstr "Hossz:" msgid "Samplerate:" msgstr "Mintavételi frekvencia:" #, c-format msgid "%ld Hz" msgstr "%ld Hz" msgid "Channel count:" msgstr "Csatornák száma:" msgid "MONO" msgstr "MONO" msgid "STEREO" msgstr "STEREO" msgid "Bandwidth:" msgstr "Sávszélesség:" msgid "Total samples:" msgstr "Összes mintavétel:" msgid "Mode:" msgstr "Mód:" msgid "Type:" msgstr "Típus: " msgid "Channels:" msgstr "Csatornák:" msgid "Patterns:" msgstr "Minták:" msgid "Samples:" msgstr "Mintavételek:" msgid "Instruments:" msgstr "Hangszerek:" msgid "Samples" msgstr "Mintavételek:i frekvencia:" msgid "Instruments" msgstr "Hangszerek" msgid "Name" msgstr "Név" msgid "STOPPING" msgstr "MEGÁLLÍT" msgid "Output:" msgstr "Kimenet:" msgid "No output" msgstr "Nincs kimenet" msgid "SRC Type: " msgstr "SRC Típus: " #, c-format msgid "Loop range: %d-%d%% [%s - %s]" msgstr "Ismétlési tartomány: %d-%d%% [%s - %s]" #, c-format msgid "Loop range: %d-%d%%" msgstr "Ismétlési tartomány: %d-%d%%" msgid "" "One or more stores in Music Store have been modified.\n" "Do you want to save them before exiting?" msgstr "" "Zenetárban egy vagy több tároló tartalma megváltozott.\n" "Szeretnéd elmenteni őket kilépés előtt?" msgid "Do not exit" msgstr "Ne lépjen ki" msgid "Quit" msgstr "Kilépés" #, c-format msgid "Position: %d%%" msgstr "Pozíció: %d%%" #, c-format msgid "Mute" msgstr "Néma" #, c-format msgid "%d dB" msgstr "%d dB" #, c-format msgid "Volume: %s" msgstr "Hangerő: %s" #, c-format msgid "%d%% R" msgstr "%d%% R" #, c-format msgid "%d%% L" msgstr "%d%% L" #, c-format msgid "C" msgstr "C" #, c-format msgid "Balance: %s" msgstr "Balansz: %s" msgid "JACK connection lost" msgstr "Megszakadt a JACK összeköttetés" msgid "" "JACK has either been shutdown or it disconnected Aqualung because it was not " "fast enough. All you can do now is restart both JACK and Aqualung." msgstr "" "A JACK szervert leállították, vagy lekapcsolta az Aqualungot, mert nem volt " "elég gyors. Újra kell indítani a JACK-et és az Aqualungot is." msgid "Warn me if the Window Manager does not support system tray" msgstr "Figyelmeztetés, ha az ablakkezelő nem támogatja a rendszertálcát" msgid "" "Aqualung is compiled with system tray support, but the status icon could not " "be embedded in the notification area. Your desktop may not have support for " "a system tray, or it has not been configured correctly." msgstr "" "Az Aqualung támogatja a rendszertálca használatát, de az állapotikont nem " "sikerült a tálcára helyezni. Lehet, hogy az asztalodról hiányzik a " "rendszertálca, vagy nincs megfelelően beállítva." msgid "Settings" msgstr "Beállítások" msgid "Skin chooser" msgstr "Szkin-választó" msgid "JACK port setup" msgstr "JACK port beállítás" msgid "Previous song" msgstr "Előző szám" msgid "Stop" msgstr "Megállítás" msgid "Next song" msgstr "Következő szám" msgid "Play/Pause" msgstr "Lejátszás/Szünet" msgid "Play" msgstr "Lejátszás" msgid "Pause" msgstr "Szünet" msgid "Repeat current song" msgstr "Aktuális szám ismétlése" msgid "Repeat all songs" msgstr "Összes szám ismétlése" msgid "Shuffle songs" msgstr "Véletlenszerű sorrend" msgid "Toggle playlist" msgstr "Lejátszólista" msgid "Toggle music store" msgstr "Zenetár" msgid "Toggle LADSPA patch builder" msgstr "LADSPA effekt szerkesztő" msgid "Show Aqualung" msgstr "Aqualung mutatása" msgid "Hide Aqualung" msgstr "Aqualung elrejtése" msgid "Previous" msgstr "Előző" msgid "Next" msgstr "Következő" #, c-format msgid "%.1f MB / %.1f MB" msgstr "%.1f MB / %.1f MB" #, c-format msgid "%d / %d files" msgstr "%d / %d fájl" #, c-format msgid "%d / %d directories" msgstr "%d / %d könyvtár" msgid "Cannot write to selected directory. Please select another directory." msgstr "A kiválasztott könyvtárba nem lehet írni, válassz egy másikat." msgid "Done" msgstr "Kész" msgid "Aborted..." msgstr "Megszakítva..." msgid "Please enter directory name." msgstr "Add meg a könyvtár nevét." msgid "Create directory" msgstr "Könyvtár létrehozása" msgid "Please enter a new name." msgstr "Adj meg egy új nevet." msgid "Rename" msgstr "Átnevezés" #, c-format msgid "" "Directory '%s' will be removed with its entire contents.\n" "\n" "Do you want to proceed?" msgstr "" "Biztosan el akarod távolítani a '%s' könyvtárat\n" "és teljes tartalmát?" #, c-format msgid "" "File '%s' will be removed.\n" "\n" "Do you want to proceed?" msgstr "Biztosan el akarod távolítani a '%s' fájl?" msgid "Remove" msgstr "Eltávolítás" #, c-format msgid " (%.1f MB)" msgstr " (%.1f MB)" #, c-format msgid " (capacity = %.1f MB)" msgstr " (kapacitás = %.1f MB)" #, c-format msgid " Free space (%.1f MB)" msgstr " Szabad hely (%.1f MB)" msgid "" "No suitable iRiver iFP device found.\n" "Perhaps it is unplugged or turned off." msgstr "" "Nem található megfelelő iRiver iFP eszköz.\n" "Lehet, hogy nincs csatlakoztatva, vagy ki van kapcsolva." msgid "" "Device is busy.\n" "(Aqualung was unable to claim its interface.)" msgstr "" "Az eszköz foglalt.\n" "(Nem sikerült hozzáférni az interfészhez.)" msgid "" "Device is not responding.\n" "Try jiggling the handle." msgstr "" "Az eszköz nem válaszol.\n" "Próbáld mozgatni a fogantyúját." msgid "Please select a local path." msgstr "Válassz egy helyi elérési utat." msgid "Please select at least one valid song from playlist." msgstr "Válassz ki legalább egy érvényes számot a lejátszólistából." #, c-format msgid "" "One song has format unsupported by your player.\n" "\n" "Do you want to proceed?" msgstr "" "A lejátszód nem támogatja az egyik szám formátumát.\n" "\n" "Akarod folytatni?" #, c-format msgid "" "%d of %d songs have format unsupported by your player.\n" "\n" "Do you want to proceed?" msgstr "" "A lejátszód %d szám formátumát nem támogatja a megadott %d közül.\n" "\n" "Akarod folytatni?" #, c-format msgid "" "The selected song has format unsupported by your player.\n" "\n" "Do you want to proceed?" msgstr "" "A lejátszód nem támogatja a kiválasztott szám formátumát.\n" "\n" "Akarod folytatni?" #, c-format msgid "" "None of the selected songs has format supported by your player.\n" "\n" "Do you want to proceed?" msgstr "" "A lejátszód egyik kiválasztott szám formátumát sem támogatja.\n" "\n" "Akarod folytatni?" msgid "iFP device manager (upload mode)" msgstr "iFP eszközkezelő (feltöltés mód)" msgid "iFP device manager (download mode)" msgstr "iFP eszközkezelő (letöltés mód)" msgid "Selected files:" msgstr "Kiválasztott fájlok:" msgid "Songs info" msgstr "Szám info" msgid "Model:" msgstr "Modell:" msgid "Battery" msgstr "Elem" msgid "Free space" msgstr "Szabad hely" msgid "Device status" msgstr "Eszköz állapota" msgid "Size" msgstr "Méret" msgid "Create a new directory" msgstr "Új könyvtár létrehozása" msgid "Remote directory" msgstr "Távoli könyvtár" msgid "Local directory" msgstr "Helyi könyvtár" msgid "Browse" msgstr "Tallózás" msgid "File name: " msgstr "Fájlnév:" msgid "Current file: " msgstr "Aktuális fájl: " msgid "Overall: " msgstr "Összesen: " msgid "Idle" msgstr "Tétlen" msgid "Transfer progress" msgstr "Másolási folyamat" msgid "Close window when transfer complete" msgstr "Ablak bezárása, ha kész" msgid "_Upload" msgstr "_Feltöltés" msgid "_Download" msgstr "_Letöltés" msgid "_Abort" msgstr "_Megszakítás" msgid "Success" msgstr "Siker" msgid "Memory allocation error" msgstr "Memória foglalási hiba" msgid "Unable to open file" msgstr "Sikertelen fájlmegnyitás" msgid "No metadata support for this format" msgstr "A formátum nem támogat metaadatot" msgid "File is not writable" msgstr "A fájl nem írható" msgid "Invalid 'Track no.' field value" msgstr "A 'Track no.' mező értéke érvénytelen" msgid "Invalid 'Genre' field value" msgstr "A 'Genre' mező értéke érvénytelen" msgid "Conversion to target charset failed" msgstr "Nem sikerült konvertálni a megadott karakterkészletre." msgid "Internal error" msgstr "Internal error" msgid "Unknown error" msgstr "Ismeretlen hiba" msgid "Album" msgstr "Lemez" msgid "Date" msgstr "Dátum" msgid "Genre" msgstr "Műfaj" msgid "Track No." msgstr "Track száma" msgid "Comment" msgstr "Megjegyzés" msgid "Disc" msgstr "Disc" msgid "Performer" msgstr "Előadó" msgid "Description" msgstr "Leírás" msgid "Organization" msgstr "Szervezet" msgid "Location" msgstr "Hely" msgid "Contact" msgstr "Kapcsolat" msgid "License" msgstr "Licenc" msgid "Copyright" msgstr "Copyright" msgid "ISRC" msgstr "ISRC" msgid "Version" msgstr "Verzió" msgid "Subtitle" msgstr "Alcím" msgid "Debut Album" msgstr "Debütáló lemez" msgid "Publisher" msgstr "Kiadó" msgid "Conductor" msgstr "Karmester" msgid "Composer" msgstr "Zeneszerző" msgid "Publication Right" msgstr "Publikáció joga" msgid "File" msgstr "Fájl" msgid "EAN/UPC" msgstr "EAN/UPC" msgid "ISBN" msgstr "ISBN" msgid "Catalog Number" msgstr "Katalógus szám" msgid "Label Code" msgstr "Címke kód" msgid "Record Date" msgstr "Felvétel dátuma" msgid "Record Location" msgstr "Felvétel helye" msgid "Media" msgstr "Média" msgid "Index" msgstr "Index" msgid "Related" msgstr "Kapcsolódó" msgid "Abstract" msgstr "Absztrakt" msgid "Language" msgstr "Nyelv" msgid "Bibliography" msgstr "Irodalomjegyzék" msgid "Introplay" msgstr "Introplay" msgid "BPM" msgstr "BPM" msgid "Encoding Time" msgstr "Kódolás ideje" msgid "Playlist Delay" msgstr "Lejátszólista késleltetés" msgid "Original Release Time" msgstr "Eredeti kiadás ideje" msgid "Release Time" msgstr "Kiadás ideje" msgid "Tagging Time" msgstr "Taggelés ideje" msgid "Encoded by" msgstr "Kódoló" msgid "Lyricist/Text Writer" msgstr "Szövegíró" msgid "File Type" msgstr "Fájltípus" msgid "Involved People" msgstr "Résztvevő emberek" msgid "Content Group" msgstr "Tartalom csoport" msgid "Initial key" msgstr "Kezdeti előjegyzés" msgid "Musician Credits" msgstr "Zenészek elismerése" msgid "Mood" msgstr "Hangnem" msgid "Original Album" msgstr "Eredeti album" msgid "Original Filename" msgstr "Eredeti fájlnév" msgid "Original Lyricist" msgstr "Eredeti szövegíró" msgid "Original Artist" msgstr "Eredeti előadó" msgid "File Owner" msgstr "Fájl tulajdonosa" msgid "Band/Orchestra" msgstr "Zenekar/orchestra" msgid "Interpreted/Remixed" msgstr "Feldolgozás/remix" msgid "Part Of A Set" msgstr "Összetett mű része" msgid "Produced" msgstr "Produced" msgid "Internet Radio Station Name" msgstr "Internetes rádióállomás neve" msgid "Internet Radio Station Owner" msgstr "Internetes rádióállomás tulajdonosa" msgid "Album Sort Order" msgstr "Album sorrendje" msgid "Performer Sort Order" msgstr "Előadó sorrendje" msgid "Title Sort Order" msgstr "Cím sorrendje" msgid "Software" msgstr "Szoftver" msgid "Set Subtitle" msgstr "Összetett mű alcíme" msgid "User Defined Text" msgstr "Felhasználói szöveg" msgid "Commercial Information" msgstr "Kereskedelmi információ" msgid "Copyright/Legal Information" msgstr "Copyright/Legal információ" msgid "Official Audio File Website" msgstr "Audio fájl hivatalos honlapja" msgid "Official Artist Website" msgstr "Szerző hivatalos honlapja" msgid "Official Audio Source Website" msgstr "Audió forrás hivatalos honlapja" msgid "Official Radio Station Website" msgstr "Rádióállomás hivatalos honlapja" msgid "Payment" msgstr "Fizetés" msgid "Publisher's Official Website" msgstr "Kiadó hivatalos honlapja" msgid "User Defined URL" msgstr "Felhasználói URL" msgid "Vendor" msgstr "Vendor" msgid "ReplayGain Reference Loudness" msgstr "ReplayGain referencia hangosság" msgid "ReplayGain Track Gain" msgstr "ReplayGain Track Gain" msgid "ReplayGain Track Peak" msgstr "ReplayGain Track Peak" msgid "ReplayGain Album Gain" msgstr "ReplayGain Album Gain" msgid "ReplayGain Album Peak" msgstr "ReplayGain Album Peak" msgid "Icy-Name" msgstr "Icy-Név" msgid "Icy-Description" msgstr "Icy-Leírás" msgid "Icy-Genre" msgstr "Icy-Műfaj:" msgid "RVA" msgstr "RVA" msgid "Attached Picture" msgstr "Csatolt kép" msgid "Binary Object" msgstr "Bináris objektum" msgid "NULL" msgstr "NULL" msgid "ID3v1" msgstr "ID3v1" msgid "ID3v2" msgstr "ID3v2" msgid "APE" msgstr "APE" msgid "Ogg Xiph Comments" msgstr "Ogg Xiph megjegyzések" msgid "FLAC Pictures" msgstr "FLAC kép" msgid "Musepack ReplayGain" msgstr "Musepack ReplayGain" msgid "Generic StreamMeta" msgstr "Általános StreamMeta" msgid "MPEG StreamMeta" msgstr "MPEG StreamMeta" msgid "Module info" msgstr "Modul infó" msgid "Unknown" msgstr "Ismeretlen" msgid "Other" msgstr "Egyéb" msgid "File icon (32x32 PNG)" msgstr "Fájl ikon (32x32 PNG)" msgid "File icon (other)" msgstr "Fájl ikon (egyéb)" msgid "Front cover" msgstr "Első borító" msgid "Back cover" msgstr "Hátsó borító" msgid "Leaflet page" msgstr "Füzetlap" msgid "Album image" msgstr "Album kép" msgid "Lead artist/performer" msgstr "Vezető művész/előadó" msgid "Artist/performer" msgstr "Művész/előadó" msgid "Band/orchestra" msgstr "Zenekar/orchestra" msgid "Lyricist/text writer" msgstr "Szövegíró" msgid "Recording location/studio" msgstr "Felvétel helye/stúdió" msgid "During recording" msgstr "Felvétel közben" msgid "During performance" msgstr "Előadás közben" msgid "Movie/video screen capture" msgstr "Mozi/videó felvétel" msgid "A large, coloured fish" msgstr "Egy nagy, színes hal" msgid "Illustration" msgstr "Illusztráció" msgid "Band/artist logotype" msgstr "Zenekar/előadó logótípus" msgid "Publisher/studio logotype" msgstr "Kiadó/stúdió logótípus" msgid "Music Store" msgstr "Zenetár" msgid "Search..." msgstr "Keresés..." msgid "Collapse all items" msgstr "Elemek bezárása" msgid "Edit item..." msgstr "Elem szerkesztése..." msgid "Add item..." msgstr "Elem hozzáadása..." msgid "Remove item..." msgstr "Elem eltávolítása" msgid "Save all stores" msgstr "Összes tároló mentése" msgid "Create empty store..." msgstr "Üres tároló létrehozása..." msgid "*Music Store" msgstr "*Zenetár" #, c-format msgid "Do you want to save store \"%s\" before removing from Music Store?" msgstr "" "El akarod menteni a(z) \"%s\" tárolót mielőtt eltávolítod a Zenetárból?" msgid "" "You will need to restart Aqualung for the following changes to take effect:" msgstr "" "A következő változtatások az Aqualung újraindítása után jutnak érvényre:" msgid "Select a font..." msgstr "Font választása..." msgid "Disable skin support" msgstr "Szkinek tiltása" msgid "rw" msgstr "rw" msgid "r" msgstr "r" msgid "unreachable" msgstr "nem elérhető" msgid "Please select a Programable Title Format File." msgstr "Válassz egy címformátum-leíró fájlt." msgid "Please select a Music Store database." msgstr "Válassz egy adatbázist." msgid "Paths must either be absolute or starting with a tilde." msgstr "Abszolút vagy tildével kezdődő elérési út szükséges." msgid "The specified store has already been added to the list." msgstr "A megadott tároló már szerepel a listában." #, c-format msgid "" "\n" "The template string you enter here will be used to construct a single title " "line from an Artist, a Record and a Track name. These are denoted by %%%%a, %" "%%%r and %%%%t, respectively.\n" msgstr "" "\n" "Az alábbi sablon az előadó nevéből, valamint a lemez- és számcímekből " "összeállított címsor formátumát adja meg. A %%%%a, %%%%r és %%%%t vezérlők " "rendre az előadót, a lemezt és a szám címét jelölik.\n" msgid "" "\n" "The file you enter/choose here will set the Lua program to use to format the " "title. See the Aqualung manual for details. Here is a quick example of what " "you can use in the file:\n" "\n" "function playlist_title()\n" " return m('artist') .. '-' .. m('title') .. ' (' .. m('album') .. ') (' .. i" "('filename') .. ')'\n" "end" msgstr "" "\n" "Az alábbi fájl a címek formázását írja elő a Lua program számára. A funkció " "részletes leírása a manualban olvasható. Egy rövid példa a fájl tartalmára:\n" "\n" "function playlist_title()\n" " return m('artist') .. '-' .. m('title') .. ' (' .. m('album') .. ') (' .. i" "('filename') .. ')'\n" "end" msgid "" "\n" "The string you enter here will be parsed as a command line before parsing " "the actual command line parameters. What you enter here will act as a " "default setting and may or may not be overridden from the 'real' command " "line.\n" "\n" "Example: enter '-o alsa -R' below to use ALSA output running realtime as a " "default.\n" msgstr "" "\n" "Az alábbi szöveget a program parancssorként értelmezi, az aktuális " "parancssor feldolgozása előtt. Az ide írt kapcsolók alapértelmezett " "beállításokként működnek, amelyeket a valódi parancssori paraméterek " "felülbírálhatnak.\n" "\n" "Például a '-o alsa -R' az ALSA kimenet valós idejű használatát írja elő " "alapértelmezettként.\n" msgid "" "Paths must either be absolute or starting with a tilde, which will be " "expanded to the user's home directory.\n" "\n" "Drag and drop entries in the list to set the store order in the Music Store." msgstr "" "Abszolút vagy tildével kezdődő elérési utak szükségesek.\n" "A tilde a saját könyvtár elérési útját jelenti.\n" "\n" "A lista elemeinek átrendezésével állítható a tárolók sorrendje a Zenetárban." msgid "" "\n" "Set the drive speed for CD playing in CD-ROM speed units. One speed unit " "equals to 176 kBps raw data reading speed. Warning: not all drives honor " "this setting.\n" "\n" "Lower speed usually means less drive noise. However, when using Paranoia " "error correction modes for increased accuracy, generally much larger speeds " "are required to prevent buffer underruns (and thus audible drop-outs).\n" "\n" "Please note that these settings do not apply to CD Ripping, which always " "happens with maximum available speed and with error correction modes " "manually set before every run." msgstr "" "\n" "CD lejátszás sebességének beállítása CD-ROM sebesség egységekben. Egy egység " "megfelel 176 kBps nyers adat olvasási sebességnek. Figyelmeztetés: nem " "minden meghajtó veszi figyelembe ezt a beállítást.\n" "\n" "Kisebb sebesség általában alacsonyabb zajt eredményez. Viszont a nagyobb " "pontosság érdekében használható Paranoia hibajavítás sokszor magasabb " "sebességet követel, hogy elejét vegye a buffer kiürülésének (és ezáltal a " "hallható kihagyásoknak).\n" "\n" "Fontos, hogy ezek a beállítások nem vonatkoznak a CD rippelésre, ami mindig " "a lehető legnagyobb sebességgel történik. A hibajavítás külön beállítható " "minden rippelés előtt." msgid "" "\n" "Most drives let Aqualung know when a CD has been inserted or removed by " "providing a 'media changed' flag. However, some drives don't set this flag " "properly, and thus it may happen that a newly inserted CD remains unnoticed " "to Aqualung. In such cases, enabling this option should help." msgstr "" "\n" "A legtöbb meghajtó egy 'media changed' jelzőn keresztül értesítést küld egy " "CD berakásáról vagy kivételéről. Néhány meghajtó viszont nem használja " "megfelelően ezt a jelzőt, ezért előfordulhat, hogy egy újonnan betett CD " "észrevétlen marad. Ilyen esetekben segíthet ezen opció engedélyezése." msgid "" "\n" "Here you should enter a comma-separated list of domains\n" "that should be accessed without using the proxy set above.\n" "Example: localhost, .localdomain, .my.domain.com" msgstr "" "\n" "Azon domainek vesszővel elválasztott felsorolása, amelyek\n" "eléréséhez ne használja a fent beállított proxyt.\n" "Példa: localhost, .localdomain, .my.domain.com" msgid "Embed playlist into main window" msgstr "A Lejátszólista beágyazása a főablakba" msgid "Enable systray" msgstr "Rendszertálca engedélyezése" msgid "Do nothing" msgstr "Ne csináljon semmit" msgid "Change volume" msgstr "Hangerő változtatása" msgid "Change balance" msgstr "Balansz változtatása" msgid "Change song position" msgstr "Számon belül pozíció változtatás" msgid "Change current song" msgstr "Aktuális szám léptetése" msgid "Left button" msgstr "Bal gomb" msgid "Middle button" msgstr "Középső gomb" msgid "Right button" msgstr "Jobb gomb" msgid "Button" msgstr "Gomb" msgid "Left and right mouse buttons are reserved." msgstr "A bal és jobb gombok funkciója nem változtatható." msgid "This button is already assigned." msgstr "Ez a gomb már be van állítva." msgid "Add mouse button command" msgstr "Egérgomb funckió hozzáadása" msgid "Mouse button" msgstr "Egérgomb" msgid "Click here to set mouse button" msgstr "Kattints ide az egérgomb beállításához" msgid "Command" msgstr "Parancs" msgid "Main window" msgstr "Főablak" msgid "Disable control buttons relief" msgstr "Vezérlőgombok kiemelkedésének tiltása" msgid "Combine play and pause buttons" msgstr "Lejátszás és szünet gombok egyesítése" msgid "Keep main window always on top" msgstr "A főablak legyen mindig felül" msgid "Show song name in the main window's title" msgstr "Szám címének megjelenítése a főablak címsorában" msgid "Title Format" msgstr "Címformátum" msgid "Programmable title format file" msgstr "Címformátum-leíró fájl" msgid "Systray" msgstr "Rendszertálca" msgid "Start minimized" msgstr "Indítás minimalizálva" msgid "Play/Stop song" msgstr "Lejátszás indítása/megállítás" msgid "Play/Pause song" msgstr "Lejátszás indítása/szünet" msgid "Mouse wheel" msgstr "Egér görgő" msgid "Vertical mouse wheel:" msgstr "Függőleges egér görgő" msgid "Horizontal mouse wheel:" msgstr "Vízszintes egér görgő" msgid "Mouse buttons" msgstr "Egérgombok" msgid "Miscellaneous" msgstr "Egyéb" msgid "Implicit command line" msgstr "Implicit parancssor" msgid "Cover art" msgstr "Lemezborító" msgid "Default cover width:" msgstr "Alapértelmezett borítóméret:" msgid "50 pixels" msgstr "50 képpont" msgid "100 pixels" msgstr "100 képpont" msgid "200 pixels" msgstr "200 képpont" msgid "300 pixels" msgstr "300 képpont" msgid "use browser window width" msgstr "ablak szélességéhez igazít" msgid "Do not magnify images with smaller width" msgstr "A kisebb képeket ne nagyítsa" msgid "Show cover thumbnail for Music Store tracks only" msgstr "Borító mutatása csak a Zenetárból hozzáadott számok esetén" msgid "Don't show cover thumbnail in the main window" msgstr "Ne jelenjen meg a borító képe a főablakban" msgid "Enable tooltips" msgstr "Buboréksúgók engedélyezése" msgid "Simple view in LADSPA patch builder" msgstr "Egyszerű nézet a LADSPA effekt szerkesztőben" msgid "United windows minimization" msgstr "Ablakok együttes minimalizálása" msgid "Show hidden files and directories in file choosers" msgstr "Rejtett fájlok és könyvtárak mutatása tallózáskor" msgid "Show tags tab first in the file info dialog" msgstr "Először a tagek látszódjanak a fájl infó ablakban" msgid "Playlist" msgstr "Lejátszólista" msgid "Put control buttons at the bottom of playlist" msgstr "Vezérlőgombok elhelyezése a Lejátszólista alján" msgid "Save and restore the playlist on exit/startup" msgstr "Lejátszólista mentése és visszatöltése kilépéskor/indításkor" msgid "Save playlist periodically [min]:" msgstr "Lejátszólista rendszeres mentési ideje [perc]:" msgid "Album mode is the default when adding entire records" msgstr "Lemezek alapértelmezett hozzáadása album módban" msgid "Always show the tab bar" msgstr "Mindig látszódjanak a fülek" msgid "Show close button in tab" msgstr "Legyen bezárás gomb a füleken" msgid "When shuffling, records added in Album mode are played in order" msgstr "Véletlenszerű lejátszás esetén albumon belüli számsorrend megtartása" msgid "Enable statusbar" msgstr "Állapotsor engedélyezése" msgid "Enable statusbar in playlist" msgstr "Állapotsor engedélyezése a Lejátszólistában" msgid "Show soundfile size in statusbar" msgstr "Hangfájl méretének mutatása az állapotsorban" msgid "Show RVA values" msgstr "RVA értékek megjelenítése" msgid "Show track lengths" msgstr "Szám hosszak megjelenítése" msgid "Show active track name in bold" msgstr "Aktív szám megjelenítése félkövérrel" msgid "Automatically roll to active track" msgstr "Automatikus görgetés az aktív számhoz" msgid "Enable rules hint" msgstr "Sorok vonalazása" msgid "Playlist column order" msgstr "Oszlopok sorrendje a Lejátszólistában" msgid "" "Drag and drop entries in the list below \n" "to set the column order in the Playlist." msgstr "" "Az alábbi lista elemeinek átrendezésével\n" "állítható a Lejátszólista oszlopainak sorrendje." msgid "Column" msgstr "Oszlop" msgid "Track titles" msgstr "Számcímek" msgid "RVA values" msgstr "RVA értékek" msgid "Track lengths" msgstr "Szám hosszak" msgid "Hide comment pane" msgstr "Komment mező elrejtése" msgid "Hide the Music Store comment pane" msgstr "A Zenetár komment mezőjének elrejtése" msgid "Enable toolbar" msgstr "Eszköztár engedélyezése" msgid "Enable toolbar in Music Store" msgstr "Eszköztár engedélyezése a Zenetárban" msgid "Enable statusbar in Music Store" msgstr "Állapotsor engedélyezése a Zenetárban" msgid "Expand Stores on startup" msgstr "Tárolók lenyitása indításkor" msgid "Enable tree node icons" msgstr "Ikonok engedélyezése a csomópontokban" msgid "Enable Music Store tree node icons" msgstr "Ikonok engedélyezése a Zenetár csomópontjaiban" msgid "Ask for confirmation when removing items" msgstr "Megerősítés elemek törlése előtt" msgid "Paths to Music Store databases" msgstr "A Zenetár adatbázisok elérési útja" msgid "Path" msgstr "Elérési út" msgid "Access" msgstr "Hozzáférés" msgid "Refresh" msgstr "Frissítés" msgid "DSP" msgstr "DSP" msgid "LADSPA plugin processing" msgstr "LADSPA effekt processzálás" msgid "Pre Fader (before Volume & Balance)" msgstr "Pre Fader (Hangerő- és balanszszabályozó előtt)" msgid "Post Fader (after Volume & Balance)" msgstr "Post Fader (Hangerő és balanszszabályozó után)" msgid "" "Aqualung is compiled without LADSPA plugin support.\n" "See the About box and the documentation for details." msgstr "" "Az Aqualungot LADSPA plugin támogatás nélkül fordították.\n" "Részletek a Névjegyben és a dokumentációban." msgid "Sample Rate Converter type" msgstr "Mintavételi frekvencia konverter típusa" msgid "" "Aqualung is compiled without Sample Rate Converter support.\n" "See the About box and the documentation for details." msgstr "" "Az Aqualungot mintavételi frekvencia konverter támogatás nélkül\n" "fordították. Részletek a Névjegyben és a dokumentációban." msgid "Playback RVA" msgstr "Lejátszáskori RVA" msgid "Enable playback RVA" msgstr "Lejátszáskori RVA használata" msgid "Listening environment:" msgstr "Lehallgatási környezet:" msgid "Audiophile" msgstr "Audiofil" msgid "Living room" msgstr "Nappali szoba" msgid "Office" msgstr "Iroda" msgid "Noisy workshop" msgstr "Zajos műhely" msgid "Reference volume [dBFS] :" msgstr "Referencia-hangerőszint [dBFS] :" msgid "Steepness [dB/dB] :" msgstr "Meredekség [dB/dB] :" msgid "RVA for Unmeasured Files [dB] :" msgstr "RVA meghatározatlan hangosságú fájlokhoz [dB] :" msgid "Apply averaged RVA to tracks of the same record" msgstr "Egyazon lemez számaira átlagolt RVA alkalmazása" msgid "Drop statistical aberrations based on" msgstr "Beszámítás az átlagba, ha belül van:" #, no-c-format msgid "% of standard deviation" msgstr "a szórás megadott %-án" msgid "Linear threshold [dB]" msgstr "az átlagtól vett eltérésen [dB]" msgid "Linear threshold [dB] :" msgstr "Max. eltérés az átlagtól [dB] :" #, no-c-format msgid "% of standard deviation :" msgstr "Max. eltérés a szórás %-ában :" msgid "ReplayGain tag to use (with fallback to the other): " msgstr "ReplayGain tag kiválasztása (a másik tartalék lesz): " msgid "Replaygain_track_gain" msgstr "Replaygain_track_gain" msgid "Replaygain_album_gain" msgstr "Replaygain_album_gain" msgid "Adding files to Playlist" msgstr "Fájlok hozzáadása a Lejátszólistához" msgid "" "Use basename only instead of full path\n" "if no metadata is available." msgstr "" "Fájlnév használata teljes elérési út helyett\n" "ha nincs elérhető metaadat." msgid "Metadata editor (File info dialog)" msgstr "Metaadat szerkesztő (Fájl infó ablak)" msgid "" "When adding new frames, try to set their contents\n" "from another tag's equivalent frame." msgstr "" "Új keret hozzáadásánál próbálja meg beállítani a\n" "tartalmát egy másik tag ekvivalens keretéből." msgid "Batch update & encode (mass tagger, CD ripper, file export)" msgstr "" "Frissítés a háttérben & kódolás (taggelés, CD rippelés, fájlok exportálása)" msgid "Tags to add when creating or updating MPEG audio files:" msgstr "" "MPEG audio fájlokban létrehozáskor vagy frissítéskor hozzáadandó keretek:" msgid "" "Note: pre-existing tags will be updated even though they\n" "might not be checked here." msgstr "" "Megjegyzés: a korábban meglévő tagek akkor is frissülnek,\n" "ha itt nincsenek bejelölve." msgid "CD Audio" msgstr "CD Audio" msgid "CD drive speed:" msgstr "CD meghajtó sebesség:" msgid "\tMaximum number of retries:" msgstr "\tÚjrapróbálások maximális száma:" msgid "Force TOC re-read on every drive scan" msgstr "TOC újraolvasás kényszerítése minden meghajtó scannelésnél" msgid "Automatically add CDs to Playlist" msgstr "CD-k automatikus hozzáadása a Lejátszólistához" msgid "Automatically remove CDs from Playlist" msgstr "CD-k automatikus eltávolítása a Lejátszólistából" msgid "CDDB server:" msgstr "CDDB szerver:" msgid "Connection timeout [sec]:" msgstr "Kapcsolódás időkorlátja [sec]:" msgid "Email address for submission:" msgstr "Email cím feltöltéshez:" msgid "Local CDDB directory:" msgstr "Helyi CDDB könyvtár:" msgid "Use the local database only" msgstr "Kizárólag a helyi adatbázis használata" msgid "Protocol for querying (direct connection only):" msgstr "Lekérdezési protokoll (közvetlen kapcsolódás esetén):" msgid "CDDBP (port 888)" msgstr "CDDBP (port 888)" msgid "HTTP (port 80)" msgstr "HTTP (port 80)" msgid "Internet" msgstr "Internet" msgid "Direct connection to the Internet" msgstr "Közvetlen Internetkapcsolat" msgid "Connect via HTTP proxy" msgstr "Csatlakozás HTTP proxy-n keresztül" msgid "Proxy settings" msgstr "Proxy beállítások" msgid "Proxy host:" msgstr "Proxy host:" msgid "Port:" msgstr "Port:" msgid "No proxy for:" msgstr "Nincs proxy:" msgid "Timeout for socket I/O:" msgstr "Socket I/O időkorlátja:" msgid "seconds" msgstr "másodperc" msgid "Appearance" msgstr "Megjelenés" msgid "Override skin settings" msgstr "Szkin beállítások felülbírálása" msgid "Fonts" msgstr "Betűtípusok" msgid "Playlist: " msgstr "Lejátszólista: " msgid "Music Store: " msgstr "Zenetár: " msgid "Big timer: " msgstr "Nagy időkijelző: " msgid "Small timers: " msgstr "Kis időkijelzők: " msgid "Song title: " msgstr "Szám címe: " msgid "Song info: " msgstr "Szám info: " msgid "Statusbar: " msgstr "Állapotsor: " msgid "Colors" msgstr "Színek" msgid "Song in playlist: " msgstr "Szám a Lejátszólistában: " msgid "Active song in playlist: " msgstr "Aktív szám a Lejátszólistában: " msgid "Error in title format string" msgstr "Hiba a címformátum sablonban" msgid "(Untitled)" msgstr "(Névtelen)" #, c-format msgid " (%d/%d)" msgstr " (%d/%d)" msgid "Select files" msgstr "Fájlok kiválasztása" msgid "Select directory" msgstr "Könyvtár kiválasztása" msgid "Add URL" msgstr "URL hozzáadása" msgid "URL:" msgstr "URL:" msgid "Please specify the file to save the playlist to." msgstr "Add meg az elmentendő lejátszólista fájlt." msgid "Please specify the file to load the playlist from." msgstr "Add meg a betöltendő lejátszólista fájlt." msgid "" "Playback RVA is currently disabled.\n" "Do you want to enable it now?" msgstr "" "A lejátszáskori RVA jelenleg nem engedélyezett.\n" "Akarod most engedélyezni?" msgid "counting..." msgstr "számolás alatt..." msgid "track" msgstr "szám" msgid "tracks" msgstr "szám" msgid "Rename playlist" msgstr "Lejátszólista átnevezése" msgid "Name:" msgstr "Név:" msgid "New tab" msgstr "Új lap" msgid "Close tab" msgstr "Lap bezárása" msgid "Undo close tab" msgstr "Lapbezárás visszavonása" msgid "Close other tabs" msgstr "Többi lap bezárása" msgid " Selected: " msgstr " Kijelölve: " msgid "Total: " msgstr "Összesen: " msgid "Add files" msgstr "Fájlok hozzáadása" msgid "" "Add files to playlist\n" "(Press right mouse button for menu)" msgstr "" "Fájlok hozzáadása a listához\n" "(jobb egérgomb: helyi menü)" msgid "Select all" msgstr "Összes elem kijelölése" msgid "" "Select all songs in playlist\n" "(Press right mouse button for menu)" msgstr "" "A lejátszólista összes számának kijelölése\n" "(jobb egérgomb: helyi menü)" msgid "Remove selected" msgstr "Kijelölt elemek törlése" msgid "" "Remove selected songs from playlist\n" "(Press right mouse button for menu)" msgstr "" "Kijelölt számok törlése a lejátszólistából\n" "(jobb egérgomb: helyi menü)" msgid "Add directory" msgstr "Könyvtár hozzáadása" msgid "Select none" msgstr "Kijelölés megszüntetése" msgid "Invert selection" msgstr "Kijelölés megfordítása" msgid "Remove all" msgstr "Mindent eltávolít" msgid "Remove dead" msgstr "Érvénytelen elemek eltávolítása" msgid "Cut selected" msgstr "Kijelölt elemek megtartása" msgid "Save playlist" msgstr "Lejátszólista mentése" msgid "Save all playlists" msgstr "Összes lejátszólista mentése" msgid "Load playlist in new tab" msgstr "Lejátszólista betöltése új lapon" msgid "Load playlist" msgstr "Lejátszólista betöltése" msgid "Enqueue playlist" msgstr "Lejátszólista hozzáfűzése" msgid "Send to iFP device" msgstr "Küldés iFP eszközre" msgid "Calculate RVA" msgstr "Hangosság meghatározása" msgid "Separate" msgstr "Egyéni" msgid "Average" msgstr "Átlagos" msgid "Reread file metadata" msgstr "Metaadatok újraolvasása" msgid "File info..." msgstr "Fájl infó..." msgid "Roll to active song" msgstr "Aktív számra ugrás" msgid "Stop adding files" msgstr "Hozzáadás leállítása" msgid "Files selected for removal" msgstr "Törlésre kijelölt fájlok" msgid "Remove files" msgstr "Fájlok törlése" msgid "" "The selected files will be deleted from the filesystem. No recovery will be " "possible after this operation.\n" "\n" "Do you want to proceed?" msgstr "" "A kiválasztott fájlok törlődni fognak a fájlrendszerről. Végrehajtás után " "nem lesz lehetőség visszaállításra.\n" "\n" "Biztosan folytatni akarod?" #, c-format msgid "Unable to remove %d file." msgstr "%d fájl törlése sikertelen volt." #, c-format msgid "Unable to remove %d files." msgstr "%d fájl törlése sikertelen volt." msgid "LADSPA patch builder" msgstr "LADSPA effekt szerkesztő" msgid "Available plugins" msgstr "Rendelkezésre álló effektek" msgid "ID" msgstr "ID" msgid "Category" msgstr "Kategória" msgid "Inputs" msgstr "Bemenetek" msgid "Outputs" msgstr "Kimenetek" msgid "Running plugins" msgstr "Működő effektek" msgid "_Configure" msgstr "_Beállítás" msgid "Enable all plugins" msgstr "Összes effekt engedélyezése" msgid "Disable all plugins" msgstr "Összes effekt letiltása" msgid "Invert current state" msgstr "Aktuális állapot invertálása" msgid "Clear list" msgstr "Lista törlése" msgid "Untitled" msgstr "Névtelen" msgid "JACK Port Setup" msgstr "JACK port beállítás" msgid "Rescan" msgstr "Újraolvas" msgid "Available connections" msgstr "Elérhető összeköttetések" msgid "Clear connections" msgstr "Összeköttetések törlése" msgid " out L" msgstr " out L" msgid " out R" msgstr " out R" msgid "Search the Music Store" msgstr "Keresés a Zenetárban" msgid "Key: " msgstr "Kulcs:" msgid "Case sensitive" msgstr "Kis/nagybetűk különböznek" msgid "Exact matches only" msgstr "Csak teljes egyezés" msgid "Select first and close window" msgstr "Első találat kiválasztása és az ablak bezárása" msgid "Search in:" msgstr "Keresés a következő helyeken:" msgid "Artist names" msgstr "Előadók" msgid "Record titles" msgstr "Albumok" msgid "Comments" msgstr "Megjegyzések" msgid "Search" msgstr "Keresés" msgid "Search the Playlist" msgstr "Keresés a Lejátszólistában" msgid "Available skins" msgstr "Elérhető szkinek" msgid "Drive info" msgstr "Meghajtó infó" msgid "Device path:" msgstr "Elérési út:" msgid "Vendor:" msgstr "Vendor:" msgid "Revision:" msgstr "Revision:" msgid "" "The information below is reported by the drive, and\n" "may not reflect the actual capabilities of the device." msgstr "" "Az alábbi információ a meghajtótól származik, ami lehet\n" "hogy nem felel meg a készülék valódi képességeinek." msgid "Eject" msgstr "Tálca kitolása" msgid "Close tray" msgstr "Tálca behúzása" msgid "Disable manual eject" msgstr "Tálca kézi kitolásának tiltása" msgid "Select juke-box disc" msgstr "Juke-box lemez kiválasztása" msgid "Set drive speed" msgstr "Meghajtó sebesség beállítása" msgid "Detect media change" msgstr "Lemezcsere érzékelése" msgid "Read multiple sessions" msgstr "Több session olvasása" msgid "Hard reset device" msgstr "Eszköz hard resetelése" msgid "Reading" msgstr "Olvasás" msgid "Play CD Audio" msgstr "Audio CD lejátszása" msgid "Read CD-DA" msgstr "CD-DA olvasása" msgid "Read CD+G" msgstr "CD+G olvasása" msgid "Read CD-R" msgstr "CD-R olvasása" msgid "Read CD-RW" msgstr "CD-RW olvasása" msgid "Read DVD-R" msgstr "DVD-R olvasása" msgid "Read DVD+R" msgstr "DVD+R olvasása" msgid "Read DVD-RW" msgstr "DVD-RW olvasása" msgid "Read DVD+RW" msgstr "DVD+RW olvasása" msgid "Read DVD-RAM" msgstr "DVD-RAM olvasása" msgid "Read DVD-ROM" msgstr "DVD-ROM olvasása" msgid "C2 Error Correction" msgstr "C2 hibajavítás" msgid "Read Mode 2 Form 1" msgstr "Mode 2 Form 1 olvasása" msgid "Read Mode 2 Form 2" msgstr "Mode 2 Form 2 olvasása" msgid "Read MCN" msgstr "MCN olvasása" msgid "Read ISRC" msgstr "ISRC olvasása" msgid "Writing" msgstr "Írás" msgid "Write CD-R" msgstr "CD-R írása" msgid "Write CD-RW" msgstr "CD-RW írása" msgid "Write DVD-R" msgstr "DVD-R írása" msgid "Write DVD+R" msgstr "DVD+R írása" msgid "Write DVD-RW" msgstr "DVD-RW írása" msgid "Write DVD+RW" msgstr "DVD+RW írása" msgid "Write DVD-RAM" msgstr "DVD-RAM írása" msgid "Mount Rainier" msgstr "Mount Rainier" msgid "Burn Proof" msgstr "Burn Proof" msgid "Disc info" msgstr "Lemez infó" msgid "This CD does not contain CD-Text information." msgstr "Ez a lemez nem tartalmaz CD-Text információt." msgid "drive" msgstr "meghajtó" msgid "drives" msgstr "meghajtó" msgid "record" msgstr "album" msgid "records" msgstr "album" msgid "Add to playlist" msgstr "Lejátszólistába" msgid "Add to playlist (Album mode)" msgstr "Lejátszólistába (Album mód)" msgid "CDDB query for this CD..." msgstr "CD lekérdezése CDDB adatbázisból..." msgid "Submit CD to CDDB database..." msgstr "CD feltöltése CDDB adatbázisba..." msgid "Rip CD..." msgstr "CD rippelés..." msgid "Disc info..." msgstr "Lemez infó..." msgid "Drive info..." msgstr "Meghajtó infó..." msgid "Comments:" msgstr "Megjegyzések:" msgid "Please select the xml file for this store." msgstr "Add meg a tárolóhoz tartozó xml fájlt." msgid "Create empty store" msgstr "Üres tároló létrehozása" msgid "Visible name:" msgstr "Látható név:" msgid "Edit Store" msgstr "Tároló szerkesztése" msgid "Use relative paths in store file" msgstr "Relatív elérési utak használata a tároló fájlban" msgid "Add Artist" msgstr "Előadó hozzáadása" msgid "Name to sort by:" msgstr "Rendezési kulcs:" msgid "Edit Artist" msgstr "Előadó szerkesztése" msgid "Please select the audio files for this record." msgstr "Válaszd ki az albumhoz adandó hangfájlokat." msgid "Add Record" msgstr "Album hozzáadása" msgid "Auto-create tracks from these files:" msgstr "Számok automatikus létrehozása a következő fájlokból:" msgid "_Add files..." msgstr "Fájlok _hozzáadása..." msgid "Edit Record" msgstr "Album szerkesztése" msgid "Please select the audio file for this track." msgstr "Add meg a számhoz tartozó fájlt." msgid "Add Track" msgstr "Szám hozzáadása" msgid "Edit Track" msgstr "Szám szerkesztése" msgid "Duration:" msgstr "Hossz:" #, c-format msgid "Unmeasured" msgstr "Ismeretlen" msgid "Volume level:" msgstr "Hangerő:" msgid "Use manual RVA value [dB]" msgstr "Rögzített RVA használata [dB]" #, c-format msgid "Really remove \"%s\" from the Music Store?" msgstr "Biztosan eltávolítod a Zenetárból a következőt: \"%s\" ?" msgid "Stop adding songs" msgstr "Hozzáadás leállítása" #, c-format msgid "" "The store '%s' already exists.\n" "Add it on the Settings/Music Store tab." msgstr "" "A '%s' táróló már létezik.\n" "Hozzáadása a Beállítások/Zenetár oldalon lehetséges." #, c-format msgid "Really remove store \"%s\" from the Music Store?" msgstr "Biztosan eltávolítod a Zenetárból a \"%s\" tárolót?" msgid "Remove Store" msgstr "Tároló eltávolítása" msgid "Do you want to save the store before removing?" msgstr "El akarod menteni a tárolót eltávolítás előtt?" msgid "Remove Artist" msgstr "Előadó eltávolítása" msgid "Remove Record" msgstr "Album eltávolítása" msgid "Remove Track" msgstr "Szám eltávolítása" msgid "Update file metadata" msgstr "Metaadatok frissítése" msgid "Track name" msgstr "Szám címe" msgid "Track comment" msgstr "Szám kommentje" msgid "Track number" msgstr "Track száma" msgid "Failed to set metadata for the following files:" msgstr "A következő fájloknál nem sikerült beállítani a metaadatokat:" msgid "Filename" msgstr "Fájlnév" msgid "Reason" msgstr "Hiba oka" msgid "(no comment)" msgstr "(nincs megjegyzés)" msgid "artist" msgstr "előadó" msgid "artists" msgstr "előadó" #, c-format msgid "" "File \"%s\" does not exist or your write permission has been withdrawn. " "Check if the partition containing the store file has been unmounted." msgstr "" "A megadott fájl \"%s\" nem létezik, vagy visszavonták róla az írási jogot. " "Lehetséges, hogy a fájlt tartalmazó partíciót lecsatolták." msgid "Build / Update store from filesystem..." msgstr "Tároló felépítése / aktualizálása fájlrendszerről..." msgid "Edit store..." msgstr "Tároló szerkesztése..." msgid "Export store..." msgstr "Tároló exportálása..." msgid "Save store" msgstr "Tároló mentése" msgid "Remove store" msgstr "Tároló eltávolítása" msgid "Add new artist to this store..." msgstr "Új előadó hozzáadása ehhez a tárolóhoz..." msgid "Calculate volume (recursive)" msgstr "Hangosság meghatározása (rekurzív)" msgid "Unmeasured tracks only" msgstr "Ismeretlen hangerejű számokra" msgid "All tracks" msgstr "Minden számra" msgid "Batch-update file metadata..." msgstr "Metaadatok frissítése a háttérben..." msgid "Add new artist..." msgstr "Új előadó hozzáadása..." msgid "Edit artist..." msgstr "Előadó szerkesztése..." msgid "Export artist..." msgstr "Előadó exportálása..." msgid "Remove artist" msgstr "Előadó eltávolítása" msgid "Add new record to this artist..." msgstr "Új album hozzáadása ehhez az előadóhoz..." msgid "Add new record..." msgstr "Új album hozzáadása..." msgid "Edit record..." msgstr "Album szerkesztése..." msgid "Export record..." msgstr "Album exportálása..." msgid "Remove record" msgstr "Album eltávolítása" msgid "Add new track to this record..." msgstr "Új szám hozzáadása ehhez az albumhoz..." msgid "CDDB query for this record..." msgstr "Album lekérdezése CDDB adatbázisból..." msgid "Submit record to CDDB database..." msgstr "Album feltöltése CDDB adatbázisba..." msgid "Add new track..." msgstr "Új szám hozzáadása..." msgid "Edit track..." msgstr "Szám szerkesztése..." msgid "Export track..." msgstr "Szám exportálása..." msgid "Remove track" msgstr "Szám eltávolítása" msgid "Calculate volume" msgstr "Hangosság meghatározása" msgid "Only if unmeasured" msgstr "Csak ha ismeretlen" msgid "In any case" msgstr "Minden esetben" msgid "Update file metadata..." msgstr "Metaadatok frissítése..." msgid "Please select the download directory for this podcast." msgstr "Válassz ki egy könyvtárat a podcasthoz letöltendő fájloknak." msgid "Subscribe to new feed" msgstr "Új forrás felvétele" msgid "Edit feed settings" msgstr "Forrás beállításainak szerkesztése" msgid "Podcast URL:" msgstr "Podcast URL:" msgid "Download directory:" msgstr "Letöltési könyvtár:" msgid "Auto-check interval [hour]:" msgstr "Automatikus ellenőrzés ideje [óra]:" msgid "" "Automatic update has been disabled for all feeds\n" "in the Podcasts store popup menu." msgstr "" "A források automatikus frissítése ki van kapcsolva\n" "a Podcasts tároló menüjében." msgid "Limits" msgstr "Limitek" msgid "Maximum number of items:" msgstr "Adások maximális száma:" msgid "Remove older items [day]:" msgstr "Régebbi adások törlése [nap]:" msgid "Maximum space to use [MB]:" msgstr "Maximális helyhasználat [MB]:" msgid "Podcasts" msgstr "Podcasts" msgid "Updating..." msgstr "Frissítés..." msgid "Delete downloaded items from the filesystem" msgstr "Letöltött adások törlése a fájlrendszerről" msgid "Remove feed" msgstr "Forrás eltávolítása" #, c-format msgid "Really remove '%s' from the Music Store?" msgstr "Biztosan eltávolítod a Zenetárból a következőt: \"%s\" ?" msgid "Reorder feeds" msgstr "Források sorrendjének beállítása" msgid "" "Drag and drop entries in the list\n" "to set the feed order in the Music Store." msgstr "" "Az alábbi lista elemeinek átrendezésével\n" "állítható a Zenetárban lévő források sorrendje." #, c-format msgid "Downloading %d/%d (%d%%) ..." msgstr "Letöltés %d/%d (%d%%) ..." msgid "item" msgstr "adás" msgid "items" msgstr "adás" msgid "new item" msgstr "új adás" msgid "new items" msgstr "új adás" msgid "feed" msgstr "forrás" msgid "feeds" msgstr "forrás" msgid "Export item..." msgstr "Adás exportálása..." msgid "Add all items to playlist" msgstr "Összes elem lejátszólistához adása" msgid "Add all items to playlist (Album mode)" msgstr "Összes elem lejátszólistához adása (Album mód)" msgid "Add new items to playlist" msgstr "Új elemek lejátszólistához adása" msgid "Add new items to playlist (Album mode)" msgstr "Új elemek lejátszólistához adása (Album mód)" msgid "Edit feed" msgstr "Forrás szerkesztése" msgid "Export all items..." msgstr "Összes adás exportálása..." msgid "Export new items..." msgstr "Új adások exportálása..." msgid "Update feed" msgstr "Forrás frissítése" msgid "Abort ongoing update" msgstr "Frissítés megszakítása" msgid "Update all feeds" msgstr "Összes forrás frissítése" msgid "Automatically update feeds" msgstr "Források automatikus frissítése" msgid "Unexpected end of string after '?'." msgstr "A '?' után vége van a sablonnak." msgid "Expected '}' after '{', but end of string found." msgstr "A sablonban hiányzik a '}' végzárójel." #, c-format msgid "Unknown conversion type character found after '%%%%'." msgstr "Ismeretlen konverziós karakter a '%%%%' után." msgid "Unknown conversion type character found after '?'." msgstr "Ismeretlen konverziós karakter a '?' után." msgid "day" msgstr "nap" msgid "days" msgstr "nap" msgid "All Files" msgstr "Minden fájl" msgid "Extended Title Format Files (*.lua)" msgstr "Címformátum-leíró fájlok (*.lua)" msgid "Music Store Files (*.xml)" msgstr "Zenetár fájlok (*.xml)" msgid "Aqualung playlist (*.xml)" msgstr "Aqualung lejátszólista (*.xml)" msgid "MP3 Playlist (*.m3u)" msgstr "MP3 lejátszólista (*.m3u) " msgid "Multimedia Playlist (*.pls)" msgstr "Multimédia lejátszólista (*.pls)" msgid "All Playlist Files" msgstr "Minden lejátszólista" msgid "All Audio Files" msgstr "Minden hangfájl" msgid "Sound Files (*.wav, *.aiff, *.au, ...)" msgstr "Hangfájlok (*.wav, *.aiff, *.au, ...)" msgid "Free Lossless Audio Codec (*.flac)" msgstr "Free Lossless Audio Codec (*.flac)" msgid "MPEG Audio (*.mp3, *.mpa, *.mpega, ...)" msgstr "MPEG Audio (*.mp3, *.mpa, *.mpega, ...)" msgid "Ogg Vorbis (*.ogg)" msgstr "Ogg Vorbis (*.ogg)" msgid "Ogg Speex (*.spx)" msgstr "Ogg Speex (*.spx)" msgid "Musepack (*.mpc)" msgstr "Musepack (*.mpc)" msgid "Monkey's Audio Codec (*.ape)" msgstr "Monkey's Audio Codec (*.ape)" msgid "Modules (*.xm, *.mod, *.it, *.s3m, ...)" msgstr "Modulok (*.xm, *.mod, *.it, *.s3m, ...)" msgid "Compressed modules (*.gz, *.bz2)" msgstr "Tömörített modulok (*.gz, *.bz2)" msgid "Compressed modules (*.gz)" msgstr "Tömörített modulok (*.gz)" msgid "Compressed modules (*.bz2)" msgstr "Tömörített modulok (*.bz2)" msgid "WavPack (*.wv)" msgstr "WavPack (*.wv)" msgid "LAVC audio/video files" msgstr "LAVC hang/videó fájlok" msgid "Resume" msgstr "Folytatás" msgid "Calculating volume level" msgstr "Hangosság meghatározása" msgid "Profile: Telephone" msgstr "Profile: Telephone" msgid "Profile: Thumb" msgstr "Profile: Thumb" msgid "Profile: Radio" msgstr "Profile: Radio" msgid "Profile: Standard" msgstr "Profile: Standard" msgid "Profile: Xtreme" msgstr "Profile: Xtreme" msgid "Profile: Insane" msgstr "Profile: Insane" msgid "Profile: Braindead" msgstr "Profile: Braindead" msgid "Layer I" msgstr "I. Réteg" msgid "Layer II" msgstr "II. Réteg" msgid "Layer III" msgstr "III. Réteg" msgid "Unrecognized" msgstr "Ismeretlen" msgid "Single channel" msgstr "Egycsatornás" msgid "Dual channel" msgstr "Kétcsatornás" msgid "Joint stereo" msgstr "Kapcsolt sztereó" msgid "Stereo" msgstr "Sztereó" msgid "Emphasis: none" msgstr "Előkiemelés: nincs" msgid "Emphasis:" msgstr "Előkiemelés:" msgid "Emphasis: reserved" msgstr "Előkiemelés: fenntartott" msgid "bit signed" msgstr "bites előjeles egész" msgid "bit unsigned" msgstr "bites előjel nélküli egész" msgid "bit float" msgstr "bites lebegőpontos" msgid "bit double" msgstr "bites dupla pontosságú lebegőpontos" msgid "encoding" msgstr "kódolású" msgid "Compression: Fast" msgstr "Tömörítés: Gyors" msgid "Compression: Normal" msgstr "Tömörítés: Normál" msgid "Compression: High" msgstr "Tömörítés: Magas" msgid "Compression: Extra High" msgstr "Tömörítés: Extra magas" msgid "Compression: Insane" msgstr "Tömörítés: Elmebeteg" aqualung-0.9beta11/src/po/it.po0000644000175000001440000017232611331334210013275 00000000000000# translation of it.po to Italiano # Copyright (C) 2004 Tom Szilagyi # This file is distributed under the same license as the aqualung package. # # Michele Petrecca , 2007, 2008. msgid "" msgstr "" "Project-Id-Version: it\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2008-04-18 23:07+0200\n" "PO-Revision-Date: 2008-04-19 21:55+0200\n" "Last-Translator: Michele Petrecca \n" "Language-Team: Italiano\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: KBabel 1.11.4\n" msgid "About" msgstr "Altro" msgid "Build version: " msgstr "Versione:" msgid "Homepage:" msgstr "Homepage:" msgid "Authors:" msgstr "Autori" msgid "Core design, engineering & programming:\n" msgstr "Core design, engineering & programming:\n" msgid "Skin support, look & feel, GUI hacks:\n" msgstr "Supporto interfaccia, look & feel, GUI hacks:\n" msgid "Programming, GUI engineering:\n" msgstr "Programming, GUI engineering:\n" msgid "Translators:" msgstr "Traduttori:" msgid "German:\n" msgstr "Tedesco:\n" msgid "Hungarian:\n" msgstr "Ungherese:\n" msgid "Italian:\n" msgstr "Italiano:\n" msgid "Russian:\n" msgstr "Russo:\n" msgid "Ukrainian:\n" msgstr "Ucraino:\n" msgid "Graphics:" msgstr "Grafici:" msgid "Logo, icons:\n" msgstr "Icone, logo:\n" msgid "This Aqualung binary is compiled with:" msgstr "Questo binario Aqualung è compilato con:" msgid "Optional features:" msgstr "Caratteristiche opzionali:" msgid "LADSPA plugin support\n" msgstr "Supporto plugin LADSPA\n" msgid "CDDA (Audio CD) support\n" msgstr "Supporto CDDA (CD Audio)\n" msgid "CDDB support\n" msgstr "Supporto CDDB\n" msgid "Sample Rate Converter support\n" msgstr "Supporto Conversione Frequenza di Campionamento\n" msgid "iRiver iFP driver support\n" msgstr "Driver supporto iRiver iFP\n" msgid "Loop playback support\n" msgstr "" msgid "Systray support\n" msgstr "Supporto Systray\n" msgid "Podcast support\n" msgstr "Supporto Podcast\n" msgid "Decoding support:" msgstr "Supporto decoding:" msgid "sndfile (WAV, AIFF, etc.)\n" msgstr "sndfile (WAV, AIFF, etc.)\n" msgid "Free Lossless Audio Codec (FLAC)\n" msgstr "Free Lossless Audio Codec (FLAC)\n" msgid "Ogg Vorbis\n" msgstr "Ogg Vorbis\n" msgid "Ogg Speex\n" msgstr "Ogg Speex\n" msgid "MPEG Audio (MPEG 1-2.5 Layer I-III)\n" msgstr "MPEG Audio (MPEG 1-2.5 Layer I-III)\n" msgid "MOD Audio (MOD, S3M, XM, IT, etc.)\n" msgstr "MOD Audio (MOD, S3M, XM, IT, etc.)\n" msgid "Musepack\n" msgstr "Musepack\n" msgid "Monkey's Audio Codec\n" msgstr "Monkey's Audio Codec\n" msgid "WavPack\n" msgstr "WavPack\n" msgid "LAVC (AC3, AAC, WavPack, WMA, etc.)\n" msgstr "LAVC (AC3, AAC, WavPack, WMA, etc.)\n" msgid "Encoding support:" msgstr "Supporto Encoding:" msgid "sndfile (WAV)\n" msgstr "sndfile (WAV)\n" msgid "LAME (MP3)\n" msgstr "LAME (MP3)\n" msgid "Output driver support:" msgstr "Driver di uscita supportato:" msgid "OSS Audio\n" msgstr "Audio OSS\n" msgid "ALSA Audio\n" msgstr "Audio ALSA\n" msgid "JACK Audio Server\n" msgstr "Server audio JACK\n" msgid "Win32 Sound API\n" msgstr "API Sound Win32\n" msgid "" "This program is free software; you can redistribute it and/or modify it " "under the terms of the GNU General Public License as published by the Free " "Software Foundation; either version 2 of the License, or (at your option) " "any later version.\n" "\n" "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.\n" "\n" "You should have received a copy of the GNU General Public License along with " "this program; if not, write to the Free Software Foundation, Inc., 675 Mass " "Ave, Cambridge, MA 02139, USA." msgstr "" "This program is free software; you can redistribute it and/or modify it " "under the terms of the GNU General Public License as published by the Free " "Software Foundation; either version 2 of the License, or (at your option) " "any later version.\n" "\n" "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.\n" "\n" "You should have received a copy of the GNU General Public License along with " "this program; if not, write to the Free Software Foundation, Inc., 675 Mass " "Ave, Cambridge, MA 02139, USA." msgid "Enabled" msgstr "Abilitato" msgid "Source" msgstr "Sorgente" msgid "CDDB" msgstr "CDDB" msgid "CDDB (not available)" msgstr "CDDB (non disponibile)" msgid "Metadata" msgstr "Metadati" msgid "Filesystem" msgstr "Filesystem" msgid "Capitalization" msgstr "Capitalizzazione" msgid "Capitalize: " msgstr "Capitalizza: " msgid "All words" msgstr "Tutte le parole" msgid "First word only" msgstr "Solo la prima parola" msgid "Force case: " msgstr "" msgid "Force other letters to lowercase" msgstr "Forze le altre lettere in minuscolo" msgid "Regular expression" msgstr "Espressione regolare" msgid "Regexp:" msgstr "Espr. regolare:" msgid "Replace:" msgstr "" msgid "Predefined transformations" msgstr "Trasformazioni predefinite" msgid "Remove file extension" msgstr "Rimuovi estensione file" msgid "Remove leading number" msgstr "" msgid "Convert underscore to space" msgstr "Converti l'underscore (_) in uno spazio" msgid "Trim leading, tailing and duplicate spaces" msgstr "" msgid "Regexp matches empty string" msgstr "Espressione regolare coincide con la stringa vuota" msgid "Please select the root directory." msgstr "Per favore seleziona la cartella principale." msgid "Select build type" msgstr "" msgid "Directory driven" msgstr "" msgid "" "Follows the directory structure to identify the artists and\n" "records. The files are added on a record basis." msgstr "" msgid "Independent" msgstr "Indipendente" msgid "" "Recursive search from the root directory for audio files.\n" "The files are processed independently, so only metadata\n" "and filename transformation are available." msgstr "" msgid "Load settings from Music Store file" msgstr "Carica le impostazioni dal Music Store File" msgid "Build/Update store" msgstr "Costruisci/Aggiorna magazzino" msgid "General" msgstr "Generale" msgid "Directory structure" msgstr "Struttura cartelle" msgid "Root path:" msgstr "Percorso principale:" msgid "_Browse..." msgstr "_Naviga..." msgid "Structure:" msgstr "Struttura:" msgid "root / record / track" msgstr "root / registrazione / traccia" msgid "root / artist / record / track" msgstr "root / artista / registrazione / traccia" msgid "root / artist / artist / record / track" msgstr "root / artista / artista / registrazione / traccia" msgid "root / artist / artist / artist / record / track" msgstr "root / artista / artista / artista / registrazione / traccia" msgid "Exclude files matching wildcard" msgstr "" msgid "Include only files matching wildcard" msgstr "Include solo i file che combaciano con le parole chiavi" msgid "Reread data for existing tracks" msgstr "Leggi di nuovo i dati per le tracce esistenti" msgid "Remove non-existing files from store" msgstr "Rimuove i file non esistenti dallo Store" msgid "Artist" msgstr "Artista" msgid "Sort artists by" msgstr "Ordina artisti per" msgid "Artist name" msgstr "Nome artista" msgid "Artist name (lowercase)" msgstr "Nome artista (minuscolo)" msgid "Directory name" msgstr "Nome cartella" msgid "Directory name (lowercase)" msgstr "Nome cartella (minuscolo)" msgid "Record" msgstr "Registrazione" msgid "Sort records by" msgstr "Ordina registrazione per" msgid "Record name" msgstr "Nome registrazione" msgid "Record name (lowercase)" msgstr "Nome registrazione (minuscolo)" msgid "Year" msgstr "Anno" msgid "Add year to the comments of new records" msgstr "Aggiungi l'anno ai commenti della nuova registrazione" msgid "Track" msgstr "Traccia" msgid "Import Replaygain tag as manual RVA" msgstr "" msgid "Import Comment tag" msgstr "Importa commenti dai tag" msgid "Sandbox" msgstr "" msgid "Filename:" msgstr "Nome file:" msgid "Test" msgstr "Testo" msgid "Building store from filesystem" msgstr "Music store in costruzione dal filesystem" msgid "Processing:" msgstr "Processamento:" msgid "Action:" msgstr "Azione:" msgid "Abort" msgstr "Annulla" msgid "Unknown Artist" msgstr "Artista sconosciuto" msgid "Unknown Record" msgstr "Registrazione sconosciuta" msgid "Scanning files" msgstr "Scansione dei file in corso" msgid "Processing metadata" msgstr "Analisi dei metadati in corso" msgid "CDDB lookup" msgstr "Cerca in CDDB" msgid "Name transformation" msgstr "Trasformazione nome" msgid "Reading file" msgstr "Lettura in corso dei file" msgid "Removing non-existing files" msgstr "Rimozione di un file non esistente" msgid "Unknown disc" msgstr "Disco sconosciuto" msgid "No disc" msgstr "Nessun disco" msgid "CDDB query" msgstr "Interrogazione CDDB" msgid "Retrieving matches from server..." msgstr "Recupero informazioni in corso dal server..." msgid "Connecting to CDDB server..." msgstr "Connessione in corso al server CDDB..." msgid "Error" msgstr "Errore" msgid "An error occurred while attempting to connect to the CDDB server." msgstr "Si è verificato un errore durante il tentativo di connessione al server CDDB." msgid "Warning" msgstr "Attenzione" msgid "No matching record found." msgstr "Nessuna registrazione coincidente con le parole della ricerca è stata trovata" msgid "Import as Sort Key" msgstr "" msgid "Import as Title" msgstr "Importa come titolo" msgid "Import as Year" msgstr "Importa in funzione dell'anno" msgid "" "Artist appears to be in all lowercase.\n" "Do you want to proceed?" msgstr "" "Il nome dell'artista sembra essere scritto tutto a lettere minuscole.\n" "Vuoi continuare?" msgid "" "Artist appears to be in all uppercase.\n" "Do you want to proceed?" msgstr "" "Il nome dell'artista sembra essere scritto tutto in lettere maiuscole.\n" "Vuoi continuare?" msgid "" "Title appears to be in all lowercase.\n" "Do you want to proceed?" msgstr "" "Il tittolo sembra essere scritto tutto a lettere minuscole.\n" "Vuoi continuare?" msgid "" "Title appears to be in all uppercase.\n" "Do you want to proceed?" msgstr "" "Il titolo sembra essere scritto tutto a lettere minuscole.\n" "Vuoi continuare?" msgid "" "It is very likely that the year is wrong.\n" "Do you want to proceed?" msgstr "" "Potrebbe darsi che l'anno non risulta corretto.\n" "Vuoi continuare?" msgid "The email address provided for submission is invalid." msgstr "L'indirizzo e-mail indicato non è valido." msgid "An error occurred while submitting the record to the CDDB server." msgstr "E' avvenuto in errore durante l'interrogazione della voce al server CDDB." msgid "Correct existing record" msgstr "Correggi le voci esistenti" msgid "Submit new record" msgstr "Inserisci una nuova voce" msgid "Matches:" msgstr "" msgid "Artist:" msgstr "Artista:" msgid "Title:" msgstr "Titolo:" msgid "Year:" msgstr "Anno:" msgid "Category:" msgstr "Categoria:" msgid "(choose a category)" msgstr "(scegli una categoria)" msgid "Genre:" msgstr "Genere:" msgid "Extended data:" msgstr "Dati estesi:" msgid "Import as Artist" msgstr "Importa come artista" msgid "Add to Comments" msgstr "Aggiungi ai commenti" msgid "Tracks" msgstr "Tracce" msgid "You have to provide an email address for CDDB submission." msgstr "Devi indicare un indirizzo e-mail per il server CDDB." msgid "Please select the directory for ripped files." msgstr "Seleziona la cartella per i file convertiti" msgid "(none)" msgstr "(nessun risultato)" msgid "fast" msgstr "veloce" msgid "best" msgstr "migliore" msgid "Compression level:" msgstr "Livello di compressione:" msgid "Bitrate [kbps]:" msgstr "Bitrate [kbps]:" msgid "Artist/Album already existing, not empty" msgstr "Artista/Album già esistente, non vuoto" msgid "" "\n" "The Music Store you selected has a matching Artist and Album, already " "containing some tracks. If you press OK, these tracks will be removed. The " "files themselves will be left intact, but they will be removed from the " "destination Music Store. Press Cancel to get back to change the Artist/Album " "or the destination Music Store." msgstr "" "\n" "Il Music Store che hai selezionato ha una coincidenza con con Artista e " "Album contenente già alcune tracce. Se premi OK, queste tracce verranno " "rimosse. Gli stessi file rimarranno integri, ma verranno rimossi dal Music " "Store di destinazione. Premi Cancella per ritornare indietro a cambiare " "Artista/Album o il Music Store di destinazione." msgid "Rip CD" msgstr "Rip CD" msgid "Album:" msgstr "Album:" msgid "Rip" msgstr "Rip" msgid "No." msgstr "N.ro" msgid "Title" msgstr "Titolo" msgid "Select" msgstr "Seleziona" msgid "All" msgstr "Tutto" msgid "None" msgstr "Nessuno" msgid "Output" msgstr "Uscita" msgid "Destination" msgstr "Destinazione" msgid "Target directory for ripped files" msgstr "Cartella di destinazione per i file rippati" msgid "Add to Music Store" msgstr "Aggiungi al Music Store" msgid "Format" msgstr "Formato" msgid "File format:" msgstr "Formato file:" msgid "VBR encoding" msgstr "Codifica VBR" msgid "Tag files with metadata" msgstr "Tag del file con i metadati" msgid "Paranoia" msgstr "Paranoia" msgid "Paranoia error correction" msgstr "Correzione d'errore con Paranoia" msgid "Perform overlapped reads" msgstr "" msgid "Verify data integrity" msgstr "Verifica integrità dei dati" msgid "Unlimited retry on failed reads (never skip)" msgstr "Numero di tentativi illimitati su letture fallite" msgid "Maximum number of retries:" msgstr "Numero massimo di tentativi:" msgid "" "\n" "Destination directory is not read-write accessible!" msgstr "" "\n" "La cartella di destinazione non è accessibile in lettura-scrittura!" msgid "Total" msgstr "Totale" msgid "(audio only)" msgstr "(solo audio)" msgid "Ripping CD tracks" msgstr "Rippaggio tracce CD in corso" msgid "Begin" msgstr "Inizio" msgid "Length" msgstr "Lunghezza" msgid "Progress" msgstr "Progresso" msgid "Close window when complete" msgstr "Chiudi la finestra quando ha terminato" msgid "Close" msgstr "Chiudi" msgid "Unknown Album" msgstr "Album sconosciuto" msgid "Unknown Track" msgstr "Traccia sconosciuta" msgid "Please select the directory for exported files." msgstr "Per favore seleziona la cartella da destinare ai file esportati." msgid "Copy" msgstr "Copia" msgid "Help" msgstr "Aiuto" #, c-format msgid "" "\n" "The template string you enter here will be used to construct the filename of " "the exported files. The Artist, Record and Track names are denoted by %%%%a, " "%%%%r and %%%%t. The track number and format-dependent file extension are " "denoted by %%%%n and %%%%x, respectively. The flag %%%%i gives an identifier " "which is unique within an export session." msgstr "" "\n" "La stringa che inserisci qui, verrà utilizzata per costruire il nome del " "file del file esportato. L'Artista, la Registrazione e il nome della Traccia " "verranno indicate con %%%%a, %%%%r e %%%%t. Il numero della traccia e il " "formato del file (estensione) verranno riportate come segue %%%%n e %%%%x, " "rispettivamente. La variabile %%%%i fornisce un identificatore unico " "all'interno di ogni sessione esportata." msgid "Export files" msgstr "Esporta file" msgid "Location and filename" msgstr "Locazione e nome del file" msgid "Target directory:" msgstr "Cartella \"obiettivo\":" msgid "Create subdirectories for artists" msgstr "Crea sottocartelle per gli artisti" msgid "Create subdirectories for albums" msgstr "Crea sottocartelle per gli album" msgid "" "Subdirectory name\n" "length limit:" msgstr "" "Nome della sottocartella\n" "lunghezza limite:" msgid "Filename template:" msgstr "Nome file del template:" msgid "Filter" msgstr "Filtro" msgid "Do not reencode files already being in the target format" msgstr "Non codificare di nuovo i file che gia' si trovano nel formato di destinazione" msgid "" "Do not reencode files\n" "matching wildcard:" msgstr "" msgid "Error in format string" msgstr "Errore nel formato della stringa" msgid "Exporting files" msgstr "Esportazione file in corso" msgid "Source file:" msgstr "File sorgente:" msgid "Target file:" msgstr "File \"obiettivo\":" msgid "Progress:" msgstr "Progresso:" msgid "*File info" msgstr "*Info file" msgid "File info" msgstr "Info file" msgid "There are unsaved changes to the file metadata." msgstr "Ci sono cambi non salvati al file dei metadati" msgid "Save and close" msgstr "Salva e chiudi" msgid "Discard changes" msgstr "Annulla i cambi" msgid "Do not close" msgstr "Non chiudere" #, c-format msgid "" "Conversion error in field %s:\n" "'%s' does not conform to format '%s'!" msgstr "" "Errore di conversione nel campo %s:\n" "'%s' non è conforme al formato '%s'!" msgid "" "Attached Picture frame with no image set!\n" "Please set an image or remove the frame." msgstr "" #, c-format msgid "" "Failed to write metadata to file.\n" "Reason: %s" msgstr "" "Non è stato possibile scrivere i metadati.\n" "Motivo: %s" #, c-format msgid "" "Error converting field %s to Year:\n" "'%s' is not an integer number!" msgstr "" "Errore di conversione del campo %s in Anni:\n" "'%s' non è un numero intero atto ad indicare un anno!" msgid "Please specify the file to save the image to." msgstr "Specifica l'immagine da salvare insieme al file" msgid "(no image)" msgstr "(nessuna immagine)" msgid "(error loading image)" msgstr "(errore caricamento immagine)" msgid "Please specify the file to load the image from." msgstr "Specifica l'immagine da caricare con il file." #, c-format msgid "" "Could not load image from:\n" "%s" msgstr "" "Non è possibile caricare l'immagine da:\n" "%s" #, c-format msgid "MIME type: %s" msgstr "Tipo MIME: %s" msgid "Picture type:" msgstr "Tipo immagine:" msgid "Description:" msgstr "Descrizione:" msgid "(no description)" msgstr "(nessuna descrizione)" msgid "Change" msgstr "Cambio" msgid "Save" msgstr "Salva" msgid "Import as Record" msgstr "Importa come registrazione" msgid "Import as Track No." msgstr "Importa come traccia N.ro" msgid "Import as RVA" msgstr "Importa come RVA" msgid "Add" msgstr "Aggiungi" msgid "field:" msgstr "campo:" msgid "tag:" msgstr "tag:" msgid "Audio CD" msgstr "CD Audio" msgid "Track:" msgstr "Traccia:" msgid "File:" msgstr "File:" msgid "Audio data" msgstr "Dati audio" msgid "Format:" msgstr "Formato:" msgid "Length:" msgstr "Lunghezza:" msgid "Samplerate:" msgstr "Campionamento:" #, c-format msgid "%ld Hz" msgstr "%ld Hz" msgid "Channel count:" msgstr "Modalita' canali:" msgid "MONO" msgstr "MONO" msgid "STEREO" msgstr "STEREO" msgid "Bandwidth:" msgstr "Banda passante:" msgid "Total samples:" msgstr "Campioni totali:" msgid "Mode:" msgstr "Modo:" msgid "Type:" msgstr "Tipo:" msgid "Channels:" msgstr "Canali:" msgid "Patterns:" msgstr "Pattern:" msgid "Samples:" msgstr "Campioni:" msgid "Instruments:" msgstr "Strumenti:" msgid "Samples" msgstr "Campioni" msgid "Instruments" msgstr "Strumenti" msgid "Name" msgstr "Nome" msgid "Output:" msgstr "Uscita:" msgid "No output" msgstr "Nessuna uscita" msgid "SRC Type: " msgstr "Tipo SRC: " msgid "" "One or more stores in Music Store have been modified.\n" "Do you want to save them before exiting?" msgstr "" "Una o più modifiche sono state fatte nel Music Store.\n" "Vuoi salvare le modifiche prima di uscire?" msgid "Do not exit" msgstr "Non uscire" msgid "Quit" msgstr "Esci" #, c-format msgid "Position: %d%%" msgstr "Posizione: %d%%" #, c-format msgid "Mute" msgstr "Mute" #, c-format msgid "%d dB" msgstr "%d dB" #, c-format msgid "Volume: %s" msgstr "Volume: %s" #, c-format msgid "%d%% R" msgstr "%d%% R" #, c-format msgid "%d%% L" msgstr "%d%% L" #, c-format msgid "C" msgstr "C" #, c-format msgid "Balance: %s" msgstr "Bilanciamento: %s" msgid "JACK connection lost" msgstr "Connessione a JACK persa" msgid "" "JACK has either been shutdown or it disconnected Aqualung because it was not " "fast enough. All you can do now is restart both JACK and Aqualung." msgstr "" "JACK è stato chiuso oppure ha disconnesso Aqualung perché il player non era " "sufficientemente veloce. Per continuare a sentire le playlist devi (ri)" "avviare entrambe." msgid "Warn me if the Window Manager does not support system tray" msgstr "Avvisami se il Window Manager non supporta la system tray" msgid "" "Aqualung is compiled with system tray support, but the status icon could not " "be embedded in the notification area. Your desktop may not have support for " "a system tray, or it has not been configured correctly." msgstr "" "Aqualung è stato compilato con il supporto alla system tray, ma lo stato " "dell'icona potrebbe non essere inserita nell'area di notificazione. " "L'ambiente desktop da te in uso potrebbe non avere il supporto alla system " "tray oppure non essere configurato in maniera appropriata." msgid "Settings" msgstr "Impostazioni" msgid "Skin chooser" msgstr "Scelta Skin" msgid "JACK port setup" msgstr "Impostazioni JACK" msgid "Previous song" msgstr "Canzone precedente" msgid "Stop" msgstr "Ferma" msgid "Next song" msgstr "Canzone successiva" msgid "Play" msgstr "Riproduci" msgid "Pause" msgstr "Pausa" msgid "Repeat current song" msgstr "Ripeti la canzone corrente" msgid "Repeat all songs" msgstr "Ripeti tutte le canzoni" msgid "Shuffle songs" msgstr "Modalità Shuffle" msgid "Toggle playlist" msgstr "Visualizza playlist" msgid "Toggle music store" msgstr "Visualizza Music Store" msgid "Toggle LADSPA patch builder" msgstr "Aggiungi effetto LADSPA" msgid "Show Aqualung" msgstr "Mostra Aqualung" msgid "Hide Aqualung" msgstr "Nascondi Aqualung" msgid "Previous" msgstr "Precedente" msgid "Next" msgstr "Successivo" #, c-format msgid "%.1f MB / %.1f MB" msgstr "%.1f MB / %.1f MB" #, c-format msgid "%d / %d files" msgstr "%d / %d file" #, c-format msgid "%d / %d directories" msgstr "%d / %d cartelle" msgid "Cannot write to selected directory. Please select another directory." msgstr "Non è possibile scrivere nella cartella indicata; indica un altro percorso." msgid "Done" msgstr "Fatto" msgid "Aborted..." msgstr "Annullato..." msgid "Please enter directory name." msgstr "Inserisci il nome della cartella." msgid "Create directory" msgstr "Crea cartella" msgid "Please enter a new name." msgstr "Inserisci un nuovo nome." msgid "Rename" msgstr "Rinomina" #, c-format msgid "" "Directory '%s' will be removed with its entire contents.\n" "\n" "Do you want to proceed?" msgstr "" "La cartella '%s' verrà rimossa insieme al suo contenuto.\n" "\n" "Sei sicuro di voler continuare?" #, c-format msgid "" "File '%s' will be removed.\n" "\n" "Do you want to proceed?" msgstr "" "Il file '%s' verrà rimosso.\n" "\n" "Sei sicuro di vole continuare?" msgid "Remove" msgstr "Rimuovi" #, c-format msgid " (%.1f MB)" msgstr " (%.1f MB)" #, c-format msgid " (capacity = %.1f MB)" msgstr " (capacità = %.1f MB)" #, c-format msgid " Free space (%.1f MB)" msgstr " Spazio libero (%.1f MB)" msgid "" "No suitable iRiver iFP device found.\n" "Perhaps it is unplugged or turned off." msgstr "" "Nessun dispositivo iRiver iFP è stato trovato.\n" "Probabilmente e' spento oppure non rilevato (se collegato)." msgid "" "Device is busy.\n" "(Aqualung was unable to claim its interface.)" msgstr "" "Dispositivo occupato.\n" "(Aqualung non è in grado di interfacciarsi con esso)" msgid "" "Device is not responding.\n" "Try jiggling the handle." msgstr "Il dispositivo non sta rispondendo." msgid "Please select a local path." msgstr "Seleziona un percorso locale." msgid "Please select at least one valid song from playlist." msgstr "Seleziona almeno una canzone dalla playlist" #, c-format msgid "" "One song has format unsupported by your player.\n" "\n" "Do you want to proceed?" msgstr "" "Una canzone presenta un formato non supportato dal lettore.\n" "\n" "Vuoi continuare?" #, c-format msgid "" "%d of %d songs have format unsupported by your player.\n" "\n" "Do you want to proceed?" msgstr "" "%d di %d canzoni presentano un formato non supportato dal lettore.\n" "\n" "Vuoi continuare?" #, c-format msgid "" "The selected song has format unsupported by your player.\n" "\n" "Do you want to proceed?" msgstr "" "La canzone selezionata presenta un formato non supportato dal lettore.\n" "\n" "Vuoi continuare?" #, c-format msgid "" "None of the selected songs has format supported by your player.\n" "\n" "Do you want to proceed?" msgstr "" "Nessuna delle canzoni selezionate presentano un formatonon supportato dal " "lettore.\n" "\n" "Vuoi continuare?" msgid "iFP device manager (upload mode)" msgstr "Gestore dispositivo iFP (modalità upload)" msgid "iFP device manager (download mode)" msgstr "Gestore dispositivo iFP (modalità download)" msgid "Selected files:" msgstr "File selezionato:" msgid "label_songs" msgstr "etichetta canzoni" msgid "Songs info" msgstr "Info canzoni" msgid "Model:" msgstr "Modello:" msgid "Battery" msgstr "Batteria" msgid "Free space" msgstr "Spazio libero" msgid "Device status" msgstr "Stato dispositivo" msgid "Size" msgstr "Ampiezza" msgid "Create a new directory" msgstr "Crea una nuova cartella" msgid "Remote directory" msgstr "Cartella remota" msgid "Local directory" msgstr "Cartella locale" msgid "Browse" msgstr "Naviga" msgid "File name: " msgstr "Nome file: " msgid "Current file: " msgstr "File corrente: " msgid "Overall: " msgstr "Globale: " msgid "Idle" msgstr "Idle" msgid "Transfer progress" msgstr "Progresso trasferimento" msgid "Close window when transfer complete" msgstr "Chiudi la finestra quando il trasferimento ha termine" msgid "_Upload" msgstr "_Upload" msgid "_Download" msgstr "_Download" msgid "_Abort" msgstr "_Annullato" msgid "Success" msgstr "L'operazione ha avuto successo" msgid "Memory allocation error" msgstr "Errore di allocazione della memoria" msgid "Unable to open file" msgstr "Impossibile aprire il file" msgid "No metadata support for this format" msgstr "Nessun metadato supportato per questo formato di file " msgid "File is not writable" msgstr "Il file non è scrivibile" msgid "Invalid 'Track no.' field value" msgstr "Il campo 'Numero traccia' presenta un valore non corretto" msgid "Invalid 'Genre' field value" msgstr "Il campo 'Genere' presenta un valore non corretto" msgid "Conversion to target charset failed" msgstr "" msgid "Internal error" msgstr "Errore interno" msgid "Unknown error" msgstr "Errore sconosciuto" msgid "Album" msgstr "Album" msgid "Date" msgstr "Data" msgid "Genre" msgstr "Genere" msgid "Track No." msgstr "Traccia N.ro" msgid "Comment" msgstr "Commento" msgid "Disc" msgstr "Disco" msgid "Performer" msgstr "Esecutore" msgid "Description" msgstr "Descrizione" msgid "Organization" msgstr "Organizzazione" msgid "Location" msgstr "Locazione" msgid "Contact" msgstr "Contatto" msgid "License" msgstr "Licenza" msgid "Copyright" msgstr "Copyright" msgid "ISRC" msgstr "ISRC" msgid "Version" msgstr "Versione" msgid "Subtitle" msgstr "Sottotitolo" msgid "Debut Album" msgstr "Album di debutto" msgid "Publisher" msgstr "Editore - Divulgatore" msgid "Conductor" msgstr "Direttore d'orchestra" msgid "Composer" msgstr "Compositore" msgid "Publication Right" msgstr "Diritti di pubblicazione" msgid "File" msgstr "File" msgid "EAN/UPC" msgstr "EAN/UPC" msgid "ISBN" msgstr "ISBN" msgid "Catalog Number" msgstr "Numero catalogo" msgid "Label Code" msgstr "Codice etichetta" msgid "Record Date" msgstr "Data della registrazione" msgid "Record Location" msgstr "Località della registrazione" msgid "Media" msgstr "Dispositivo" msgid "Index" msgstr "Indice" msgid "Related" msgstr "" msgid "Abstract" msgstr "Abstract" msgid "Language" msgstr "Lingua" msgid "Bibliography" msgstr "Bibliografia" msgid "Introplay" msgstr "" msgid "BPM" msgstr "BPM" msgid "Encoding Time" msgstr "Tempo di codifica" msgid "Playlist Delay" msgstr "" msgid "Original Release Time" msgstr "" msgid "Release Time" msgstr "" msgid "Tagging Time" msgstr "" msgid "Encoded by" msgstr "Codificato da" msgid "Lyricist/Text Writer" msgstr "" msgid "File Type" msgstr "Tipo di file" msgid "Involved People" msgstr "Persone coinvolte" msgid "Content Group" msgstr "" msgid "Initial key" msgstr "" msgid "Musician Credits" msgstr "" msgid "Mood" msgstr "" msgid "Original Album" msgstr "Album originale" msgid "Original Filename" msgstr "Nome del file originale" msgid "Original Lyricist" msgstr "Paroliere originale" msgid "Original Artist" msgstr "Artista originale" msgid "File Owner" msgstr "Proprietario del file" msgid "Band/Orchestra" msgstr "Band/Orchestra" msgid "Interpreted/Remixed" msgstr "Interpretato/Remixato" msgid "Part Of A Set" msgstr "" msgid "Produced" msgstr "Prodotto" msgid "Internet Radio Station Name" msgstr "Nome Stazione Radio Internet " msgid "Internet Radio Station Owner" msgstr "" msgid "Album Sort Order" msgstr "" msgid "Performer Sort Order" msgstr "" msgid "Title Sort Order" msgstr "" msgid "Software" msgstr "Software" msgid "Set Subtitle" msgstr "Imposta sottotitolo" msgid "User Defined Text" msgstr "" msgid "Commercial Information" msgstr "Informazione commerciale" msgid "Copyright/Legal Information" msgstr "Copyright - Informazioni Legali" msgid "Official Audio File Website" msgstr "Sito WEB file audio ufficiale" msgid "Official Artist Website" msgstr "Sito WEB ufficiale dell'artista" msgid "Official Audio Source Website" msgstr "Sito WEB ufficiale della sorgente audio" msgid "Official Radio Station Website" msgstr "Sito WEB ufficiale stazione radio" msgid "Payment" msgstr "Pagamento" msgid "Publisher's Official Website" msgstr "" msgid "User Defined URL" msgstr "" msgid "Vendor" msgstr "Vendor" msgid "ReplayGain Reference Loudness" msgstr "" msgid "ReplayGain Track Gain" msgstr "" msgid "ReplayGain Track Peak" msgstr "" msgid "ReplayGain Album Gain" msgstr "" msgid "ReplayGain Album Peak" msgstr "" msgid "Icy-Name" msgstr "" msgid "Icy-Description" msgstr "" msgid "Icy-Genre" msgstr "" msgid "RVA" msgstr "RVA" msgid "Attached Picture" msgstr "Immagine collegata" msgid "Binary Object" msgstr "Oggetto bianrio" msgid "NULL" msgstr "NULL" msgid "ID3v1" msgstr "ID3v1" msgid "ID3v2" msgstr "ID3v2" msgid "APE" msgstr "APE" msgid "Ogg Xiph Comments" msgstr "Commenti Ogg Xiph" msgid "FLAC Pictures" msgstr "Immagine FLAC" msgid "Musepack ReplayGain" msgstr "" msgid "Generic StreamMeta" msgstr "" msgid "MPEG StreamMeta" msgstr "MPEG StreamMeta" msgid "Module info" msgstr "Informazioni modulo" msgid "Unknown" msgstr "Sconosciuto" msgid "Other" msgstr "Altro" msgid "File icon (32x32 PNG)" msgstr "Icona file (32x32 PNG)" msgid "File icon (other)" msgstr "Icona file (altro)" msgid "Front cover" msgstr "Copertina frontale" msgid "Back cover" msgstr "Copertina retro" msgid "Leaflet page" msgstr "Manifesto" msgid "Album image" msgstr "Immagine album" msgid "Lead artist/performer" msgstr "Artista/Esecutore principale" msgid "Artist/performer" msgstr "Artista/Esecutore" msgid "Band/orchestra" msgstr "Band/Orchestra" msgid "Lyricist/text writer" msgstr "" msgid "Recording location/studio" msgstr "Località/Studio di registrazione" msgid "During recording" msgstr "Durata della registrazione" msgid "During performance" msgstr "" msgid "Movie/video screen capture" msgstr "" msgid "A large, coloured fish" msgstr "" msgid "Illustration" msgstr "Illustrazione" msgid "Band/artist logotype" msgstr "Logo Band/Artista" msgid "Publisher/studio logotype" msgstr "" msgid "Music Store" msgstr "Music Store" msgid "Search..." msgstr "Ricerca..." msgid "Collapse all items" msgstr "Contrae tutte le voci" msgid "Edit item..." msgstr "Edita le voci..." msgid "Add item..." msgstr "Aggiungi voce..." msgid "Remove item..." msgstr "Rimuovi voce..." msgid "Save all stores" msgstr "Salva tutti i Music Store" msgid "Create empty store..." msgstr "Crea un Music Store vuoto..." msgid "*Music Store" msgstr "*Music Store" #, c-format msgid "Do you want to save store \"%s\" before removing from Music Store?" msgstr "Vuoi salvare lo store \"%s\" prima della rimozione dal Musci Store?" msgid "You will need to restart Aqualung for the following changes to take effect:" msgstr "Necessiti di riavviare Aqualung affinché i seguenti cambi abbiano effetto:" msgid "Select a font..." msgstr "Seleziona una font..." msgid "Disable skin support" msgstr "Disabilita il supporto alle diverse interfacce" msgid "rw" msgstr "rw" msgid "r" msgstr "r" msgid "unreachable" msgstr "non raggiungibile" msgid "Please select a Music Store database." msgstr "Seleziona un database del Music Store." msgid "Paths must either be absolute or starting with a tilde." msgstr "" "L'indicazione del percorso deve essere assoluto oppure indicato tramite la " "tilde." msgid "The specified store has already been added to the list." msgstr "Lo Store specificato è stato già aggiunto alla lista." #, c-format msgid "" "\n" "The template string you enter here will be used to construct a single title " "line from an Artist, a Record and a Track name. These are denoted by %%%%a, %" "%%%r and %%%%t, respectively.\n" msgstr "" "\n" "Il modello che inserirai qui verrà utilizzato per costruire un titolo dal " "nome di un Artista, una Registrazione e una Traccia. Questo verrà indicato " "con %%%%a, %%%%r and %%%%t, rispettivamente.\n" msgid "" "\n" "The string you enter here will be parsed as a command line before parsing " "the actual command line parameters. What you enter here will act as a " "default setting and may or may not be overridden from the 'real' command " "line.\n" "\n" "Example: enter '-o alsa -R' below to use ALSA output running realtime as a " "default.\n" msgstr "" msgid "" "Paths must either be absolute or starting with a tilde, which will be " "expanded to the user's home directory.\n" "\n" "Drag and drop entries in the list to set the store order in the Music Store." msgstr "" msgid "" "\n" "Set the drive speed for CD playing in CD-ROM speed units. One speed unit " "equals to 176 kBps raw data reading speed. Warning: not all drives honor " "this setting.\n" "\n" "Lower speed usually means less drive noise. However, when using Paranoia " "error correction modes for increased accuracy, generally much larger speeds " "are required to prevent buffer underruns (and thus audible drop-outs).\n" "\n" "Please note that these settings do not apply to CD Ripping, which always " "happens with maximum available speed and with error correction modes " "manually set before every run." msgstr "" msgid "" "\n" "Most drives let Aqualung know when a CD has been inserted or removed by " "providing a 'media changed' flag. However, some drives don't set this flag " "properly, and thus it may happen that a newly inserted CD remains unnoticed " "to Aqualung. In such cases, enabling this option should help." msgstr "" msgid "" "\n" "Here you should enter a comma-separated list of domains\n" "that should be accessed without using the proxy set above.\n" "Example: localhost, .localdomain, .my.domain.com" msgstr "" msgid "Title format" msgstr "Formato del titolo" msgid "Implicit command line" msgstr "Comandi impliciti ad una shell" msgid "Miscellaneous" msgstr "Varie" msgid "Enable tooltips" msgstr "Abilita suggerimenti" msgid "Put control buttons at the bottom of playlist" msgstr "Sposta i pulsanti di controllo sotto la playlist" msgid "Disable control buttons relief" msgstr "Disabilita il rilievo per i pulsanti non attivi" msgid "Keep main window always on top" msgstr "Mantieni la finestra sopra le altre" msgid "Simple view in LADSPA patch builder" msgstr "" msgid "United windows minimization" msgstr "Minimizza in contemporanea la finestra principale e il Music Store" msgid "Show song name in the main window's title" msgstr "" "Mostra il titolo della canzone nella barra del titolo della finestra " "principale" msgid "Show hidden files and directories in file choosers" msgstr "Mostra file e cartelle nascoste nel percorso di scelta del file" msgid "Show tags tab first in the file info dialog" msgstr "" msgid "Cover art" msgstr "Copertina" msgid "Default cover width:" msgstr "Ampiezza immagine album:" msgid "50 pixels" msgstr "50 pixel" msgid "100 pixels" msgstr "100 pixel" msgid "200 pixels" msgstr "200 pixel" msgid "300 pixels" msgstr "300 pixel" msgid "use browser window width" msgstr "" msgid "Do not magnify images with smaller width" msgstr "" msgid "Show cover thumbnail for Music Store tracks only" msgstr "" msgid "Don't show cover thumbnail in the main window" msgstr "Non mostrare la miniatura dell'album nella finestra principale" msgid "Playlist" msgstr "Playlist" msgid "Embed playlist into main window" msgstr "Integra la playlist all'interno dell'area principale" msgid "Save and restore the playlist on exit/startup" msgstr "Salva la playlist all'uscita e ripristinala all'avvio" msgid "Save playlist periodically [min]:" msgstr "Salva playlist periodicamente [min]:" msgid "Album mode is the default when adding entire records" msgstr "" msgid "Always show the tab bar" msgstr "Mostra sempre la barra dei tab" msgid "Show close button in tab" msgstr "Mostra il pulsante di chiusura sul tab" msgid "When shuffling, records added in Album mode are played in order" msgstr "" msgid "Enable statusbar" msgstr "Abilita la barra di stato" msgid "Enable statusbar in playlist" msgstr "Abilita la barra di stato nella playlist" msgid "Show soundfile size in statusbar" msgstr "Mostra dimensione del file nella barra di stato" msgid "Show RVA values" msgstr "Mostra valore RVA" msgid "Show track lengths" msgstr "Mostra lunghezza della traccia" msgid "Show active track name in bold" msgstr "Mostra la traccia attiva in grassetto" msgid "Enable rules hint" msgstr "Abilita suggerimenti" msgid "Playlist column order" msgstr "Ordine delle colonne nella playlist" msgid "" "Drag and drop entries in the list below \n" "to set the column order in the Playlist." msgstr "" "Ordina le voci della lista nel riquadro sottostante \n" "per impostare l'ordine di apparizione nella playlist." msgid "Column" msgstr "Colonna" msgid "Track titles" msgstr "Titoli traccia" msgid "RVA values" msgstr "Valori RVA" msgid "Track lengths" msgstr "Lunghezza traccia" msgid "Hide comment pane" msgstr "Nascondi il pannello dei commenti" msgid "Hide the Music Store comment pane" msgstr "Nascondi il pannello dei commenti del Music Store" msgid "Enable toolbar" msgstr "Abilita toolbar" msgid "Enable toolbar in Music Store" msgstr "Abilita la toolbar nel Music Store" msgid "Enable statusbar in Music Store" msgstr "Abilita la barra di stato nel Music Store" msgid "Expand Stores on startup" msgstr "Espandi gli Store all'avvio" msgid "Enable tree node icons" msgstr "" msgid "Enable Music Store tree node icons" msgstr "" msgid "Ask for confirmation when removing items" msgstr "Chiedi conferma quando rimuovi le voci" msgid "Paths to Music Store databases" msgstr "Percorso al database del Music Store" msgid "Path" msgstr "Percorso" msgid "Access" msgstr "Accesso" msgid "Refresh" msgstr "Aggiorna" msgid "DSP" msgstr "DSP" msgid "LADSPA plugin processing" msgstr "Processamento plugin LADSPA" msgid "Pre Fader (before Volume & Balance)" msgstr "Pre Fader (prima del Volume e del Bilanciamento)" msgid "Post Fader (after Volume & Balance)" msgstr "Post Fader (dopo il Volume e il Bilanciamento)" msgid "" "Aqualung is compiled without LADSPA plugin support.\n" "See the About box and the documentation for details." msgstr "" "Aqualung è stato compilato senza il supporto per per i plugin LADSPA.\n" "Andare nella sezione \"Altro\" e leggere la documentazione per ulteriori " "dettagli." msgid "Sample Rate Converter type" msgstr "" msgid "" "Aqualung is compiled without Sample Rate Converter support.\n" "See the About box and the documentation for details." msgstr "" "Aqualung è stato compilato senza il supporto alla \"Conversione della " "frequenza di campionamento\".\n" "Si rimanda alla documentazione per ulteriori dettagli." msgid "Playback RVA" msgstr "Playback RVA" msgid "Enable playback RVA" msgstr "Abilita playback RVA" msgid "Listening environment:" msgstr "Ambiente d'ascolto:" msgid "Audiophile" msgstr "Audiofilo" msgid "Living room" msgstr "Soggiorno" msgid "Office" msgstr "Ufficio" msgid "Noisy workshop" msgstr "Locale pubblico" msgid "Reference volume [dBFS] :" msgstr "Volume di riferimento [dBFS] :" msgid "Steepness [dB/dB] :" msgstr "Pendenza [dB/dB]:" msgid "RVA for Unmeasured Files [dB] :" msgstr "" msgid "Apply averaged RVA to tracks of the same record" msgstr "Applica RVA mediato alle tracce della stessa registrazione" msgid "Drop statistical aberrations based on" msgstr "" #, no-c-format msgid "% of standard deviation" msgstr "Deviazione standard [%]" msgid "Linear threshold [dB]" msgstr "Soglia lineare [dB]" msgid "Linear threshold [dB] :" msgstr "Soglia lineare [dB] :" #, no-c-format msgid "% of standard deviation :" msgstr "[%] deviazione standard :" msgid "ReplayGain tag to use (with fallback to the other): " msgstr "" msgid "Replaygain_track_gain" msgstr "" msgid "Replaygain_album_gain" msgstr "" msgid "Adding files to Playlist" msgstr "Aggiunta file in corso alla Playlist" msgid "" "Use basename only instead of full path\n" "if no metadata is available." msgstr "" "Utilizza solo il semplice nome invece dell'intero percorso\n" "se nessun informazione (metadato) è disponibile." msgid "Metadata editor (File info dialog)" msgstr "" msgid "" "When adding new frames, try to set their contents\n" "from another tag's equivalent frame." msgstr "" msgid "Batch update & encode (mass tagger, CD ripper, file export)" msgstr "" msgid "Tags to add when creating or updating MPEG audio files:" msgstr "Tag da aggiungere quando viene creato/aggiornato un file MPEG:" msgid "" "Note: pre-existing tags will be updated even though they\n" "might not be checked here." msgstr "" msgid "CD Audio" msgstr "CD Audio" msgid "CD drive speed:" msgstr "Velocità lettore CD:" msgid "\tMaximum number of retries:" msgstr "\tMassimo numero di tentativi:" msgid "Force TOC re-read on every drive scan" msgstr "Forza di nuovo la lettura della TOC ad ogni scansione del dispositivo" msgid "Automatically add CDs to Playlist" msgstr "Aggiungi automaticamente i CD alla playlist" msgid "Automatically remove CDs from Playlist" msgstr "Rimuovi automaticamente i CD dalla playlist" msgid "CDDB server:" msgstr "Server CDDB:" msgid "Connection timeout [sec]:" msgstr "Timeout connessione [sec]:" msgid "Email address for submission:" msgstr "Indirizzo e-mail per le richieste:" msgid "Local CDDB directory:" msgstr "Cartella locale CDDB:" msgid "Use the local database only" msgstr "Usa solo il database locale" msgid "Protocol for querying (direct connection only):" msgstr "Protocollo interrogazione (solo connessione diretta):" msgid "CDDBP (port 888)" msgstr "CDDBP (porta 888)" msgid "HTTP (port 80)" msgstr "HTTP (porta 80)" msgid "Internet" msgstr "Internet" msgid "Direct connection to the Internet" msgstr "Connessione diretta ad Internet" msgid "Connect via HTTP proxy" msgstr "Connessione attraverso proxy HTTP" msgid "Proxy settings" msgstr "Impostazioni Proxy" msgid "Proxy host:" msgstr "Host proxy:" msgid "Port:" msgstr "Porta:" msgid "No proxy for:" msgstr "Nessun proxy per:" msgid "Timeout for socket I/O:" msgstr "Timeout per socket I/O:" msgid "seconds" msgstr "secondi" msgid "Appearance" msgstr "Apparenza" msgid "Override skin settings" msgstr "Modifica le impostazioni delle interfacce" msgid "Fonts" msgstr "Font" msgid "Playlist: " msgstr "Playlist: " msgid "Music Store: " msgstr "Music Store: " msgid "Big timer: " msgstr "Contatore - Cifre grandi:" msgid "Small timers: " msgstr "Contatore - Cifre piccole" msgid "Song title: " msgstr "Titolo canzone: " msgid "Song info: " msgstr "Info canzone: " msgid "Statusbar: " msgstr "Barra di stato: " msgid "Colors" msgstr "Colori" msgid "Song in playlist: " msgstr "Canzone nella playlist: " msgid "Active song in playlist: " msgstr "Traccia in esecuzione nella playlist: " msgid "Error in title format string" msgstr "Errore nel titolo (formato stringa)" msgid "(Untitled)" msgstr "(Senza titolo)" #, c-format msgid " (%d/%d)" msgstr " (%d/%d)" msgid "Select files" msgstr "Seleziona file" msgid "Select directory" msgstr "Seleziona cartella" msgid "Add URL" msgstr "Aggiungi l'URL" msgid "URL:" msgstr "URL:" msgid "Please specify the file to save the playlist to." msgstr "Specifica il file da salvare alla playlist." msgid "Please specify the file to load the playlist from." msgstr "Specifica il file da salvare dalla playlist." msgid "" "Playback RVA is currently disabled.\n" "Do you want to enable it now?" msgstr "" "Playback RVA e' attualmente disabilitato.\n" "Vuoi abilitarlo ora?" msgid "counting..." msgstr "valutazione in corso..." msgid "track" msgstr "traccia" msgid "tracks" msgstr "tracce" msgid "Rename playlist" msgstr "Rinomina plylist" msgid "Name:" msgstr "Nome:" msgid "New tab" msgstr "Nuovo tab" msgid "Close tab" msgstr "Chiudi tab" msgid "Undo close tab" msgstr "Annulla chiusura tab" msgid "Close other tabs" msgstr "Chiudi gli altri tab" msgid " Selected: " msgstr " Selezionato: " msgid "Total: " msgstr "Totale: " msgid "Add files" msgstr "Aggiungi file" msgid "" "Add files to playlist\n" "(Press right mouse button for menu)" msgstr "" "Aggiungi i file alla playlist\n" "(Premi il tasto destro del mouse per il menù)" msgid "Select all" msgstr "Seleziona tutto" msgid "" "Select all songs in playlist\n" "(Press right mouse button for menu)" msgstr "" "Seleziona tutte le tracce nella playlist\n" "(Clicca con il tasto destro del mouse per il menù)" msgid "Remove selected" msgstr "Rimuovi selezione" msgid "" "Remove selected songs from playlist\n" "(Press right mouse button for menu)" msgstr "" "Rimuovi le tracce selezionate nella playlist\n" "(Clicca con il tasto destro del mouse per il menù)" msgid "Add directory" msgstr "Aggiungi cartella" msgid "Select none" msgstr "Nessuna selezione" msgid "Invert selection" msgstr "Inverti selezione" msgid "Remove all" msgstr "Rimuovi tutto" msgid "Remove dead" msgstr "" msgid "Cut selected" msgstr "Taglia selezione" msgid "Save playlist" msgstr "Salva la playlist" msgid "Save all playlists" msgstr "Salva tutte le playlist" msgid "Load playlist in new tab" msgstr "Carica la playlist in un nuovo tab" msgid "Load playlist" msgstr "Carica playlist" msgid "Enqueue playlist" msgstr "Accoda playlist" msgid "Send to iFP device" msgstr "Trasmetti al dispositivo iFP" msgid "Calculate RVA" msgstr "Calcola RVA" msgid "Separate" msgstr "Volumi singoli" msgid "Average" msgstr "Media" msgid "Reread file metadata" msgstr "Leggi di nuovo i metadati del file" msgid "File info..." msgstr "Informazioni sul file..." msgid "Stop adding files" msgstr "" msgid "Files selected for removal" msgstr "File selezionati per la rimozione" msgid "Remove files" msgstr "Rimuovi file" msgid "" "The selected files will be deleted from the filesystem. No recovery will be " "possible after this operation.\n" "\n" "Do you want to proceed?" msgstr "" "Il file selezionato sarà cancellato dal disco. Nessun recupero sarà " "possibile dopo questa operazione.\n" "\n" "Sei sicuro di voler continuare?" #, c-format msgid "Unable to remove %d file." msgstr "Impossibile rimuovere il file %d ." #, c-format msgid "Unable to remove %d files." msgstr "Impossibile rimuovere i file %d ." msgid "LADSPA patch builder" msgstr "Finestra effetti LADSPA" msgid "Available plugins" msgstr "Plugin disponibili" msgid "ID" msgstr "ID" msgid "Category" msgstr "Categoria" msgid "Inputs" msgstr "Ingressi" msgid "Outputs" msgstr "Uscite" msgid "Running plugins" msgstr "Avvio plugin in corso" msgid "_Configure" msgstr "_Configura" msgid "Enable all plugins" msgstr "Abilita tutti i plugin" msgid "Disable all plugins" msgstr "Disabilita tutti i plugin" msgid "Invert current state" msgstr "Inverti lo stato corrente" msgid "Clear list" msgstr "Cancella la lista" msgid "Untitled" msgstr "Senza titolo" msgid "JACK Port Setup" msgstr "Impostazioni porte JACK" msgid "Rescan" msgstr "Scansiona di nuovo" msgid "Available connections" msgstr "Connessioni disponibili" msgid "Clear connections" msgstr "Cancella connessioni" msgid " out L" msgstr " uscita S" msgid " out R" msgstr " uscita D" msgid "Search the Music Store" msgstr "Ricerca il Music Store" msgid "Key: " msgstr "Parola chiave: " msgid "Case sensitive" msgstr "Distingui maiuscole" msgid "Exact matches only" msgstr "Solo le parole coincidenti" msgid "Select first and close window" msgstr "Prima seleziona, poi chiudi la finestra" msgid "Search in:" msgstr "Cerca in:" msgid "Artist names" msgstr "Nome artista" msgid "Record titles" msgstr "Titoli registrazione" msgid "Comments" msgstr "Commenti" msgid "Search" msgstr "Cerca" msgid "Search the Playlist" msgstr "Cerca la Playlist" msgid "Available skins" msgstr "Skin disponibili" msgid "Drive info" msgstr "Informazioni driver" msgid "Device path:" msgstr "Percorso dispositivo:" msgid "Vendor:" msgstr "Vendor:" msgid "Revision:" msgstr "Revisione:" msgid "" "The information below is reported by the drive, and\n" "may not reflect the actual capabilities of the device." msgstr "" "Le informazioni in basso sono riportate dal driver e\n" "potrebbero non riflettere le attuali capacità del dispositivo." msgid "Eject" msgstr "Espelli" msgid "Close tray" msgstr "Chiudi carrello" msgid "Disable manual eject" msgstr "Disabilita l'espulsione manuale" msgid "Select juke-box disc" msgstr "" msgid "Set drive speed" msgstr "Imposta velocità del lettore" msgid "Detect media change" msgstr "Rileva cambio dispositivo" msgid "Read multiple sessions" msgstr "Leggi sessioni multiple" msgid "Hard reset device" msgstr "Azzeramento forzato del dispositivo" msgid "Reading" msgstr "Lettura in corso" msgid "Play CD Audio" msgstr "Riproduci CD Audio" msgid "Read CD-DA" msgstr "Leggi CD-DA" msgid "Read CD+G" msgstr "Leggi CD+G" msgid "Read CD-R" msgstr "Leggi CD-R" msgid "Read CD-RW" msgstr "Leggi CD-RW" msgid "Read DVD-R" msgstr "Leggi DVD-R" msgid "Read DVD+R" msgstr "Leggi DVD+R" msgid "Read DVD-RW" msgstr "Leggi DVD-RW" msgid "Read DVD+RW" msgstr "Leggi DVD+RW" msgid "Read DVD-RAM" msgstr "Leggi DVD-RAM" msgid "Read DVD-ROM" msgstr "Leggi DVD-ROM" msgid "C2 Error Correction" msgstr "Correzione d'errore C2" msgid "Read Mode 2 Form 1" msgstr "Lettura Mode2/Form1" msgid "Read Mode 2 Form 2" msgstr "Lettura Mode2/Form2" msgid "Read MCN" msgstr "Leggi MCN" msgid "Read ISRC" msgstr "Leggi ISRC" msgid "Writing" msgstr "Scrittura in corso" msgid "Write CD-R" msgstr "Scrivi CD-R" msgid "Write CD-RW" msgstr "Scrivi CD-RW" msgid "Write DVD-R" msgstr "Scrivi DVD-R" msgid "Write DVD+R" msgstr "Scrivi DVD+R" msgid "Write DVD-RW" msgstr "Scrivi DVD-RW" msgid "Write DVD+RW" msgstr "Scrivi DVD+RW" msgid "Write DVD-RAM" msgstr "Scrivi DVD-RAM" msgid "Mount Rainier" msgstr "Mount Rainier" msgid "Burn Proof" msgstr "Burn Proof" msgid "Disc info" msgstr "Info Disco" msgid "This CD does not contain CD-Text information." msgstr "Questo CD non contiene informazioni di tipo CD-Text." msgid "drive" msgstr "drive" msgid "drives" msgstr "drives" msgid "record" msgstr "registrazione" msgid "records" msgstr "registrazioni" msgid "Add to playlist" msgstr "Aggiungi alla playlist" msgid "Add to playlist (Album mode)" msgstr "Aggiungi alla playlist (modalità album)" msgid "CDDB query for this CD..." msgstr "Interrogazione CDDB per questo CD..." msgid "Submit CD to CDDB database..." msgstr "Sottoponi una interogazione del CD al database CDDB..." msgid "Rip CD..." msgstr "Rip CD..." msgid "Disc info..." msgstr "Info disco..." msgid "Drive info..." msgstr "Info driver..." msgid "Comments:" msgstr "Commenti:" msgid "Please select the xml file for this store." msgstr "Seleziona il file xml per questo music store." msgid "Create empty store" msgstr "Crea uno Store vuoto" msgid "Visible name:" msgstr "Nome visibile:" msgid "Edit Store" msgstr "Modifica Store" msgid "Use relative paths in store file" msgstr "" msgid "Add Artist" msgstr "Aggiungi artista" msgid "Name to sort by:" msgstr "Nomi ordinati per:" msgid "Edit Artist" msgstr "Modifica l'artista" msgid "Please select the audio files for this record." msgstr "Seleziona i file audio per questa registrazione." msgid "Add Record" msgstr "Aggiungi registrazione" msgid "Auto-create tracks from these files:" msgstr "Crea in automatico le tracce dai seguenti file:" msgid "_Add files..." msgstr "_Aggiungi i file..." msgid "Edit Record" msgstr "Modifica registrazione" msgid "Please select the audio file for this track." msgstr "Per favore seleziona il file audio per questa traccia." msgid "Add Track" msgstr "Aggiungi traccia" msgid "Edit Track" msgstr "Edita la traccia" msgid "Duration:" msgstr "Durata:" #, c-format msgid "Unmeasured" msgstr "Non misurato" msgid "Volume level:" msgstr "Livello volume:" msgid "Use manual RVA value [dB]" msgstr "Utilizza valori opportuni del valore RVA [dB]" #, c-format msgid "Really remove \"%s\" from the Music Store?" msgstr "Vuoi veramente rimuovere \"%s\" dal Music Store?" msgid "Stop adding songs" msgstr "" #, c-format msgid "" "The store '%s' already exists.\n" "Add it on the Settings/Music Store tab." msgstr "" #, c-format msgid "Really remove store \"%s\" from the Music Store?" msgstr "Vuoi veramente rimuovere \"%s\" dal Music Store?" msgid "Remove Store" msgstr "Rimuovi il Music Store" msgid "Do you want to save the store before removing?" msgstr "Vuoi salvare il Music Store prima di rimuoverlo?" msgid "Remove Artist" msgstr "Rimuovi artista" msgid "Remove Record" msgstr "Rimuovi registrazione" msgid "Remove Track" msgstr "Rimuovi traccia" msgid "Update file metadata" msgstr "Aggiorna i metadati del file" msgid "Track name" msgstr "Nome traccia" msgid "Track comment" msgstr "Commento traccia" msgid "Track number" msgstr "Numero traccia" msgid "Failed to set metadata for the following files:" msgstr "Non è stato possibile impostare i metadati per questi file:" msgid "Filename" msgstr "Nome file" msgid "Reason" msgstr "" msgid "(no comment)" msgstr "(nessun commento)" msgid "artist" msgstr "artista" msgid "artists" msgstr "artisti" msgid "Build / Update store from filesystem..." msgstr "Costruisci / Aggiorna Music Store dal filesystem..." msgid "Edit store..." msgstr "Edita Music Store..." msgid "Export store..." msgstr "Esporta Music Store..." msgid "Save store" msgstr "Salva Music Store" msgid "Remove store" msgstr "Rimuovi Music Store" msgid "Add new artist to this store..." msgstr "Aggiungi un nuovo artista a questo Music Store..." msgid "Calculate volume (recursive)" msgstr "" msgid "Unmeasured tracks only" msgstr "Solo tracce molto lunghe" msgid "All tracks" msgstr "Tutte le tracce" msgid "Batch-update file metadata..." msgstr "" msgid "Add new artist..." msgstr "Aggiungi nuovo artista..." msgid "Edit artist..." msgstr "Edita l'artista..." msgid "Export artist..." msgstr "Esporta artista..." msgid "Remove artist" msgstr "Rimuovi artista" msgid "Add new record to this artist..." msgstr "Aggiungi una nuova registrazione a quest'artista..." msgid "Add new record..." msgstr "Aggiungi una nuova registrazione..." msgid "Edit record..." msgstr "Modifica il documento..." msgid "Export record..." msgstr "Esporta la registrazione..." msgid "Remove record" msgstr "Rimuovi registrazione" msgid "Add new track to this record..." msgstr "Aggiungi una nuova traccia all'attuale registrazione..." msgid "CDDB query for this record..." msgstr "Richiesta CDDB per il documento indicato..." msgid "Submit record to CDDB database..." msgstr "Demanda la ricerca del documento al database CDDB..." msgid "Add new track..." msgstr "Aggiungi nuova traccia..." msgid "Edit track..." msgstr "Edita la traccia..." msgid "Export track..." msgstr "Esporta la traccia..." msgid "Remove track" msgstr "Rimuovi la traccia" msgid "Calculate volume" msgstr "Calcola volume" msgid "Only if unmeasured" msgstr "Solo se non misurato" msgid "In any case" msgstr "In ogni caso" msgid "Update file metadata..." msgstr "Aggiornamento metadati del file..." msgid "Please select the download directory for this podcast." msgstr "Seleziona la cartella del downlaod per questo podcast." msgid "Subscribe to new feed" msgstr "Sottoscrivi un nuovo feed" msgid "Edit feed settings" msgstr "Modifica impostazioni feed" msgid "Podcast URL:" msgstr "URL Podcast:" msgid "Download directory:" msgstr "Cartella download:" msgid "Auto-check interval [hour]:" msgstr "Intervallo per la verifica automatica (ore):" msgid "" "Automatic update has been disabled for all feeds\n" "in the Podcasts store popup menu." msgstr "" "L'aggiornamento automatico è stato disabilitatoper\n" "tutti i feed nella pop-up dello store Podcast." msgid "Limits" msgstr "Limiti" msgid "Maximum number of items:" msgstr "Massimo numero di voci:" msgid "Remove older items [day]:" msgstr "Rimuovi le voci più vecchie [giorni]:" msgid "Maximum space to use [MB]:" msgstr "Massimo spazio da usare [MB]:" msgid "Podcasts" msgstr "Podcast" msgid "Updating..." msgstr "Aggiornamento in corso..." msgid "Delete downloaded items from the filesystem" msgstr "Cancella dal filesystem le voci scaricate" msgid "Remove feed" msgstr "Rimuovi feed" #, c-format msgid "Really remove '%s' from the Music Store?" msgstr "Vuoi veramente rimuovere '%s' dal Music Store?" msgid "Reorder feeds" msgstr "Ordina nuovamente i feed" msgid "" "Drag and drop entries in the list\n" "to set the feed order in the Music Store." msgstr "" #, c-format msgid "Downloading %d/%d (%d%%) ..." msgstr "Download in corso %d/%d (%d%%) ..." msgid "item" msgstr "voce" msgid "items" msgstr "voci" msgid "new item" msgstr "nuova voce" msgid "new items" msgstr "nuove voci" msgid "feed" msgstr "feed" msgid "feeds" msgstr "feed" msgid "Export item..." msgstr "Esporta voce..." msgid "Add all items to playlist" msgstr "Aggiungi tutte le voci alla playlist" msgid "Add all items to playlist (Album mode)" msgstr "Aggiungi tutte le voci alla playlist (modalità Album)" msgid "Add new items to playlist" msgstr "Aggiungi nuove voci alla playlist" msgid "Add new items to playlist (Album mode)" msgstr "Aggiungi nuove voci alla playlist (modalità Album)" msgid "Edit feed" msgstr "Modifica feed" msgid "Export all items..." msgstr "Esporta tutte le voci..." msgid "Export new items..." msgstr "Esporta nuove voci..." msgid "Update feed" msgstr "Aggiorna feed" msgid "Abort ongoing update" msgstr "" msgid "Update all feeds" msgstr "Aggiorna tutti i feed" msgid "Automatically update feeds" msgstr "Aggiorna automaticamente i feed" msgid "Unexpected end of string after '?'." msgstr "Inaspettata fine della stringa dopo il carattere '?'." msgid "Expected '}' after '{', but end of string found." msgstr "Era atteso il carattere '}' dopo '{', ma la stringa è terminata." #, c-format msgid "Unknown conversion type character found after '%%%%'." msgstr "" msgid "Unknown conversion type character found after '?'." msgstr "" msgid "day" msgstr "giorno" msgid "days" msgstr "giorni" msgid "All Files" msgstr "Tutti i file" msgid "Music Store Files (*.xml)" msgstr "Music Store Files (*.xml)" msgid "Aqualung playlist (*.xml)" msgstr "Playlist Aqualung (*.xml)" msgid "MP3 Playlist (*.m3u)" msgstr "Playlist MP3 (*.m3u)" msgid "Multimedia Playlist (*.pls)" msgstr "Playlist Multimediale (*.pls)" msgid "All Playlist Files" msgstr "Tutti i file della playlist" msgid "All Audio Files" msgstr "Tutti i file audio" msgid "Sound Files (*.wav, *.aiff, *.au, ...)" msgstr "File audio (*.wav, *.aiff, *.au, ...)" msgid "Free Lossless Audio Codec (*.flac)" msgstr "Free Lossless Audio Codec (*.flac)" msgid "MPEG Audio (*.mp3, *.mpa, *.mpega, ...)" msgstr "MPEG Audio (*.mp3, *.mpa, *.mpega, ...)" msgid "Ogg Vorbis (*.ogg)" msgstr "Ogg Vorbis (*.ogg)" msgid "Ogg Speex (*.spx)" msgstr "Ogg Speex (*.spx)" msgid "Musepack (*.mpc)" msgstr "Musepack (*.mpc)" msgid "Monkey's Audio Codec (*.ape)" msgstr "Monkey's Audio Codec (*.ape)" msgid "Modules (*.xm, *.mod, *.it, *.s3m, ...)" msgstr "Moduli (*.xm, *.mod, *.it, *.s3m, ...)" msgid "Compressed modules (*.gz, *.bz2)" msgstr "Moduli compressi (*.gz, *.bz2)" msgid "Compressed modules (*.gz)" msgstr "Moduli compressi (*.gz)" msgid "Compressed modules (*.bz2)" msgstr "Moduli compressi (*.bz2)" msgid "WavPack (*.wv)" msgstr "WavPack (*.wv)" msgid "LAVC audio/video files" msgstr "File LAVC audio/video" msgid "Resume" msgstr "Recupera" msgid "Calculating volume level" msgstr "Calcolo volume livello in corso" msgid "Profile: Telephone" msgstr "Profilo: Telefono" msgid "Profile: Thumb" msgstr "" msgid "Profile: Radio" msgstr "Profilo: Radio" msgid "Profile: Standard" msgstr "Profilo: Standard" msgid "Profile: Xtreme" msgstr "Profilo: Estremo" msgid "Profile: Insane" msgstr "Profilo: Insano" msgid "Profile: Braindead" msgstr "" msgid "Layer I" msgstr "Layer I" msgid "Layer II" msgstr "Layer II" msgid "Layer III" msgstr "Layer III" msgid "Unrecognized" msgstr "Non riconosciuto" msgid "Single channel" msgstr "Canale singolo" msgid "Dual channel" msgstr "Canale doppio" msgid "Joint stereo" msgstr "" msgid "Stereo" msgstr "Stereo" msgid "Emphasis: none" msgstr "Enfasi: nessuna" msgid "Emphasis:" msgstr "Enfasi:" msgid "Emphasis: reserved" msgstr "Enfasi: riservata" msgid "bit signed" msgstr "bit con segno" msgid "bit unsigned" msgstr "bit senza segno" msgid "bit float" msgstr "bit float" msgid "bit double" msgstr "bit double" msgid "encoding" msgstr "Codifica" msgid "Compression: Fast" msgstr "Compressione: Veloce" msgid "Compression: Normal" msgstr "Compressione: Normale" msgid "Compression: High" msgstr "Compressione: Alta" msgid "Compression: Extra High" msgstr "Compressione: Molto Alta" msgid "Compression: Insane" msgstr "Compressione: Insana" aqualung-0.9beta11/src/po/ja.po0000644000175000001440000023014211331334210013242 00000000000000# Japanese translations for aqualung package # Japanese messages for aqualung. # Copyright (C) 2008 Tom Szilagyi # This file is distributed under the same license as the aqualung package. # YoN , 2009 # idak , 2010 # msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2010-01-20 07:43+0900\n" "PO-Revision-Date: 2010-01-22 15:40+0100\n" "Last-Translator: YoN \n" "Language-Team: Team Puppy Linux Japan\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Poedit-Language: Japanese\n" msgid "About" msgstr "このソフトについて" msgid "Build version: " msgstr "ビルドバージョン: " msgid "Homepage:" msgstr "ホームページ:" msgid "Authors:" msgstr "作者:" msgid "Core design, engineering & programming:\n" msgstr "コアデザイン、エンジニアリングとプログラミング:\n" msgid "Skin support, look & feel, GUI hacks:\n" msgstr "スキンサポート、ルック&フィール、GUI ハック:\n" msgid "Programming, GUI engineering:\n" msgstr "プログラミング、GUI エンジニアリング:\n" msgid "OpenBSD compatibility, metadata tweaks:\n" msgstr "OpenBSD 互換、メタデータ調整:\n" msgid "Translators:" msgstr "翻訳者:" msgid "French:\n" msgstr "フランス語:\n" msgid "German:\n" msgstr "ドイツ語:\n" msgid "Hungarian:\n" msgstr "ハンガリー語:\n" msgid "Italian:\n" msgstr "イタリア語:\n" msgid "Japanese:\n" msgstr "日本語:\n" msgid "Russian:\n" msgstr "ロシア語:\n" msgid "Swedish:\n" msgstr "スウェーデン語:\n" msgid "Ukrainian:\n" msgstr "ウクライナ語:\n" msgid "Graphics:" msgstr "グラフィックス:" msgid "Logo, icons:\n" msgstr "ロゴ、アイコン:\n" msgid "This Aqualung binary is compiled with:" msgstr "この Aqualung バイナリは次のオプションでコンパイルしています:" msgid "Optional features:" msgstr "オプション機能:" msgid "LADSPA plugin support\n" msgstr "LADSPA プラグインサポート\n" msgid "CDDA (Audio CD) support\n" msgstr "CDDA (Audio CD) サポート\n" msgid "CDDB support\n" msgstr "CDDB サポート\n" msgid "Sample Rate Converter support\n" msgstr "サンプルレート変換サポート\n" msgid "iRiver iFP driver support\n" msgstr "iRiver iFP ドライバサポート\n" msgid "Loop playback support\n" msgstr "ループ再生サポート\n" msgid "Systray support\n" msgstr "システムトレイサポート\n" msgid "Podcast support\n" msgstr "ポッドキャストサポート\n" msgid "Lua (programmable title formatting) support\n" msgstr "Lua サポート (プログラム可能なタイトルフォーマット)\n" msgid "Decoding support:" msgstr "デコードサポート:" msgid "sndfile (WAV, AIFF, etc.)\n" msgstr "音声ファイル (WAV, AIFF, など)\n" msgid "Free Lossless Audio Codec (FLAC)\n" msgstr "Free Lossless Audio Codec (FLAC)\n" msgid "Ogg Vorbis\n" msgstr "Ogg Vorbis\n" msgid "Ogg Speex\n" msgstr "Ogg Speex\n" msgid "MPEG Audio (MPEG 1-2.5 Layer I-III)\n" msgstr "MPEG オーディオ (MPEG 1-2.5 Layer I-III)\n" msgid "MOD Audio (MOD, S3M, XM, IT, etc.)\n" msgstr "MOD オーディオ (MOD, S3M, XM, IT, など)\n" msgid "Musepack\n" msgstr "Musepack\n" msgid "Monkey's Audio Codec\n" msgstr "Monkey's オーディオコーデック\n" msgid "WavPack\n" msgstr "WavPack\n" msgid "LAVC (AC3, AAC, WavPack, WMA, etc.)\n" msgstr "LAVC (AC3, AAC, WavPack, WMA, など)\n" msgid "Encoding support:" msgstr "エンコードサポート:" msgid "sndfile (WAV)\n" msgstr "音声ファイル (WAV)\n" msgid "LAME (MP3)\n" msgstr "LAME (MP3)\n" msgid "Output driver support:" msgstr "出力ドライバサポート:" msgid "sndio Audio\n" msgstr "sndio オーディオ\n" msgid "OSS Audio\n" msgstr "OSS オーディオ\n" msgid "ALSA Audio\n" msgstr "ALSA オーディオ\n" msgid "JACK Audio Server\n" msgstr "JACK オーディオサーバ\n" msgid "PulseAudio\n" msgstr "PulseAudio\n" msgid "Win32 Sound API\n" msgstr "Win32 サウンド API\n" msgid "" "This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.\n" "\n" "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.\n" "\n" "You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." msgstr "" "This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.\n" "\n" "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.\n" "\n" "You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." msgid "Enabled" msgstr "有効" msgid "Source" msgstr "ソース" msgid "CDDB" msgstr "CDDB" msgid "CDDB (not available)" msgstr "CDDB (利用できません)" msgid "Metadata" msgstr "メタデータ" msgid "Filesystem" msgstr "ファイルシステム" msgid "Capitalization" msgstr "大文字にする" msgid "Capitalize: " msgstr "先頭文字を大文字:" msgid "All words" msgstr "全ての単語" msgid "First word only" msgstr "最初の単語だけ" msgid "Force case: " msgstr "大文字小文字を強制適用: " msgid "Force other letters to lowercase" msgstr "他の文字を小文字に強制適用" msgid "Regular expression" msgstr "正規表現" msgid "Regexp:" msgstr "正規表現:" msgid "Replace:" msgstr "置換:" msgid "Predefined transformations" msgstr "定義済み変換" msgid "Remove file extension" msgstr "ファイル拡張子を削除" msgid "Remove leading number" msgstr "先頭の数値を削除" msgid "Convert underscore to space" msgstr "アンダースコアを空白に変換" msgid "Trim leading, tailing and duplicate spaces" msgstr "先頭、末尾をトリミングして空白を複製" msgid "Regexp matches empty string" msgstr "正規表現に一致する空の文字列" msgid "Please select the root directory." msgstr "rootディレクトリを選択して下さい。" msgid "Select build type" msgstr "ビルドタイプを選択" msgid "Directory driven" msgstr "ディレクトリ優先" msgid "" "Follows the directory structure to identify the artists and\n" "records. The files are added on a record basis." msgstr "" "アーティストとレコードを識別するためにディレクトリ構造をたどります。\n" "レコードを基準にファイルを追加します。" msgid "Independent" msgstr "独立" msgid "" "Recursive search from the root directory for audio files.\n" "The files are processed independently, so only metadata\n" "and filename transformation are available." msgstr "" "オーディオファイルをルートディレクトリから再帰的に検索します。\n" "ファイルは独立して処理されるので、メタデータとファイル名の\n" "変換だけができます。" msgid "Load settings from Music Store file" msgstr "Music Store ファイルから設定を読み込み" msgid "Build/Update store" msgstr "ストアをビルド/更新" msgid "General" msgstr "一般" msgid "Directory structure" msgstr "ディレクトリ構造" msgid "Root path:" msgstr "ルートパス:" msgid "_Browse..." msgstr "ブラウズ(_B)..." msgid "Structure:" msgstr "構造:" msgid "root / record / track" msgstr "ルート / レコード / トラック" msgid "root / artist / record / track" msgstr "ルート / アーティスト / レコード / トラック" msgid "root / artist / artist / record / track" msgstr "ルート / アーティスト / アーティスト / レコード / トラック" msgid "root / artist / artist / artist / record / track" msgstr "ルート / アーティスト / アーティスト / アーティスト / レコード / トラック" msgid "Exclude files matching wildcard" msgstr "ワイルドカードに一致するファイルを除外" msgid "Include only files matching wildcard" msgstr "ワイルドカードに一致するファイルだけを含む" msgid "Reread data for existing tracks" msgstr "既存のトラックでデータを再読み込み" msgid "Remove non-existing files from store" msgstr "ストアから存在しないファイルを削除" msgid "Artist" msgstr "アーティスト" msgid "Sort artists by" msgstr "アーティストを並び替え" msgid "Artist name" msgstr "アーティスト名" msgid "Artist name (lowercase)" msgstr "アーティスト名 (小文字)" msgid "Directory name" msgstr "ディレクトリ名" msgid "Directory name (lowercase)" msgstr "ディレクトリ名 (小文字)" msgid "Record" msgstr "レコード" msgid "Sort records by" msgstr "レコードを並び替え" msgid "Record name" msgstr "レコード名" msgid "Record name (lowercase)" msgstr "レコード名 (小文字)" msgid "Year" msgstr "年" msgid "Add year to the comments of new records" msgstr "新しいレコードのコメントに年を追加" msgid "Track" msgstr "トラック" msgid "Import Replaygain tag as manual RVA" msgstr "マニュアル RVA として ReplayGain タグをインポート" msgid "Import Comment tag" msgstr "コメントタグをインポート" msgid "Sandbox" msgstr "サンドボックス" msgid "Filename:" msgstr "ファイル名:" msgid "Test" msgstr "テスト" msgid "Building store from filesystem" msgstr "ファイルシステムからストアをビルド" msgid "Processing:" msgstr "処理中:" msgid "Action:" msgstr "アクション:" msgid "Abort" msgstr "中止" msgid "Unknown Artist" msgstr "不明なアーティスト" msgid "Unknown Record" msgstr "不明なレコード" msgid "Scanning files" msgstr "ファイルのスキャン" msgid "Processing metadata" msgstr "メタデータの処理中" msgid "CDDB lookup" msgstr "CDDB 参照" msgid "Name transformation" msgstr "名前の変換" msgid "Reading file" msgstr "ファイルの読み取り" msgid "Removing non-existing files" msgstr "存在しないファイルの削除" msgid "Please select the directory for ripped files." msgstr "リッピングしたファイルのディレクトリを選択して下さい。" msgid "(none)" msgstr "(なし)" msgid "fast" msgstr "高速" msgid "best" msgstr "最高" msgid "Compression level:" msgstr "圧縮レベル:" msgid "Bitrate [kbps]:" msgstr "ビットレート [kbps]:" msgid "Artist/Album already existing, not empty" msgstr "アーティスト/アルバムは既に存在します。空ではありません" msgid "" "\n" "The Music Store you selected has a matching Artist and Album, already containing some tracks. If you press OK, these tracks will be removed. The files themselves will be left intact, but they will be removed from the destination Music Store. Press Cancel to get back to change the Artist/Album or the destination Music Store." msgstr "" "\n" "選択した Music Store には一致したアーティストとアルバムがあります。そして、すでにいくつかのトラックを含んでいます。 OK を押すと、このトラックは削除されます。ファイル自体は完全なまま残ります。しかし転送先の Music Store から削除されます。アーティスト/アルバムまたは転送先の Music Store の変更に戻るにはキャンセルを押して下さい。" msgid "Rip CD" msgstr "CD をリッピング" msgid "Artist:" msgstr "アーティスト:" msgid "Album:" msgstr "アルバム:" msgid "Year:" msgstr "年:" msgid "Genre:" msgstr "ジャンル:" msgid "Rip" msgstr "リッピング" msgid "No." msgstr "No." msgid "Title" msgstr "タイトル" msgid "Select" msgstr "選択" msgid "All" msgstr "全て" msgid "None" msgstr "なし" msgid "Output" msgstr "出力" msgid "Destination" msgstr "行き先" msgid "Target directory for ripped files" msgstr "リッピングしたファイルの保存先" msgid "Add to Music Store" msgstr "Music Store に追加" msgid "Format" msgstr "フォーマット" msgid "File format:" msgstr "ファイルフォーマット:" msgid "VBR encoding" msgstr "VBR エンコード" msgid "Tag files with metadata" msgstr "メタデータ付きタグファイル" msgid "Paranoia" msgstr "Paranoia" msgid "Paranoia error correction" msgstr "Paranoia エラー訂正" msgid "Perform overlapped reads" msgstr "オーバーラップした読み込みの実行" msgid "Verify data integrity" msgstr "データ整合性の確認" msgid "Unlimited retry on failed reads (never skip)" msgstr "読み込みに失敗したら無制限に再試行 (スキップしない)" msgid "Maximum number of retries:" msgstr "再試行の最大数:" msgid "Error" msgstr "エラー" msgid "" "\n" "Destination directory is not read-write accessible!" msgstr "" "\n" "目的のディレクトリは読み込み、書き込み可能ではありません!" msgid "Total" msgstr "合計" msgid "(audio only)" msgstr "(オーディオだけ)" msgid "Ripping CD tracks" msgstr "CD トラックをリッピング" msgid "Begin" msgstr "開始" msgid "Length" msgstr "長さ" msgid "Progress" msgstr "進行状況" msgid "Close window when complete" msgstr "完了したらウィンドウを閉じる" msgid "Close" msgstr "閉じる" msgid "Unknown disc" msgstr "不明な CD" msgid "No disc" msgstr "CD がありません" msgid "CDDB query" msgstr "CDDB 問い合わせ" msgid "Retrieving matches from server..." msgstr "サーバから一致を取得しています..." msgid "Connecting to CDDB server..." msgstr "CDDB サーバに接続しています..." msgid "An error occurred while attempting to connect to the CDDB server." msgstr "CDDB サーバに接続しようとしてエラーが起こりました。" msgid "Warning" msgstr "警告" msgid "No matching record found." msgstr "一致するレコードは見つかりませんでした。" msgid "Import as Sort Key" msgstr "ソートキーとしてインポート" msgid "Import as Title" msgstr "タイトルとしてインポート" msgid "Import as Year" msgstr "年としてインポート" msgid "" "Artist appears to be in all lowercase.\n" "Do you want to proceed?" msgstr "" "アーティストは全て小文字で表示されます。\n" "続けますか?" msgid "" "Artist appears to be in all uppercase.\n" "Do you want to proceed?" msgstr "" "アーティストは全て大文字で表示されます。\n" "続けますか?" msgid "" "Title appears to be in all lowercase.\n" "Do you want to proceed?" msgstr "" "タイトルは全て小文字で表示されます。\n" "続けますか?" msgid "" "Title appears to be in all uppercase.\n" "Do you want to proceed?" msgstr "" "タイトルは全て大文字で表示されます。\n" "続けますか?" msgid "" "It is very likely that the year is wrong.\n" "Do you want to proceed?" msgstr "" "年が間違っていると思われます。\n" "続けますか?" msgid "The email address provided for submission is invalid." msgstr "送信するメールアドレスが無効です。" msgid "An error occurred while submitting the record to the CDDB server." msgstr "CDDB サーバにレコードを送信中にエラーが起こりました。" msgid "Correct existing record" msgstr "既存のレコードを修正" msgid "Submit new record" msgstr "新しいレコードを送信" msgid "Matches:" msgstr "一致:" msgid "Title:" msgstr "タイトル:" msgid "Category:" msgstr "カテゴリ:" msgid "(choose a category)" msgstr "(カテゴリを選択)" msgid "Extended data:" msgstr "拡張データ:" msgid "Import as Artist" msgstr "アーティストとしてインポート" msgid "Add to Comments" msgstr "コメントに追加" msgid "Tracks" msgstr "トラック" msgid "You have to provide an email address for CDDB submission." msgstr "CDDB へ送信するにはメールアドレスを提供しなければなりません。" msgid "Unknown Album" msgstr "不明なアルバム" msgid "Unknown Track" msgstr "不明なトラック" msgid "Please select the directory for exported files." msgstr "エクスポートファイルのディレクトリを選択して下さい。" msgid "Copy" msgstr "コピー" msgid "Help" msgstr "ヘルプ" #, c-format msgid "" "\n" "The template string you enter here will be used to construct the filename of the exported files. The Artist, Record and Track names are denoted by %%%%a, %%%%r and %%%%t. The track number and format-dependent file extension are denoted by %%%%n and %%%%x, respectively. The flag %%%%i gives an identifier which is unique within an export session." msgstr "" "\n" "ここで入力するテンプレート文字列は、エクスポートされたファイルのファイル名を構築するために使われます。アーティスト、レコード、トラック名は %%%%a, %%%%r と %%%%t で表示されます。トラック番号と形式依存ファイル拡張子は %%%%n と %%%%x で表示されます。フラグ %%%%i はエクスポートセッションで固有の識別子を与えます。" msgid "Export files" msgstr "ファイルをエクスポート" msgid "Location and filename" msgstr "場所とファイル名" msgid "Target directory:" msgstr "ターゲットディレクトリ:" msgid "Create subdirectories for artists" msgstr "アーティストのサブディレクトリを作成" msgid "Create subdirectories for albums" msgstr "アルバムのサブディレクトリを作成" msgid "" "Subdirectory name\n" "length limit:" msgstr "" "サブディレクトリ名の\n" "長さ制限:" msgid "Filename template:" msgstr "ファイル名テンプレート:" msgid "Filter" msgstr "フィルタ" msgid "Do not reencode files already being in the target format" msgstr "既にターゲットフォーマットにあるファイルは再エンコードしない" msgid "" "Do not reencode files\n" "matching wildcard:" msgstr "" "ワイルドカードに一致する\n" "ファイルはエンコードしない:" msgid "Error in format string" msgstr "文字列のフォーマットにエラー" msgid "Exporting files" msgstr "エクスポートファイル" msgid "Source file:" msgstr "ソースファイル:" msgid "Target file:" msgstr "ターゲットファイル:" msgid "Progress:" msgstr "進行状況:" msgid "*File info" msgstr "*ファイル情報" msgid "File info" msgstr "ファイル情報" msgid "There are unsaved changes to the file metadata." msgstr "ファイルメタデータに保存していない変更があります。" msgid "Save and close" msgstr "保存して閉じる" msgid "Discard changes" msgstr "変更を破棄" msgid "Do not close" msgstr "閉じない" #, c-format msgid "" "Conversion error in field %s:\n" "'%s' does not conform to format '%s'!" msgstr "" "フィールド %s で変換エラー:\n" "'%s' はフォーマット '%s' に準拠しません!" msgid "" "Attached Picture frame with no image set!\n" "Please set an image or remove the frame." msgstr "" "添付画像フレームは画像が設定されていません!\n" "画像を設定するかフレームを削除して下さい。" #, c-format msgid "" "Failed to write metadata to file.\n" "Reason: %s" msgstr "" "メタデータのファイルへの書き込みに失敗。\n" "理由: %s" #, c-format msgid "" "Error converting field %s to Year:\n" "'%s' is not an integer number!" msgstr "" "フィールド %s を年に変換中にエラー:\n" "'%s' は整数ではありません!" msgid "Please specify the file to save the image to." msgstr "画像を保存するファイルを指定して下さい。" msgid "(no image)" msgstr "(イメージなし)" msgid "(error loading image)" msgstr "(イメージの読み込みエラー)" msgid "Please specify the file to load the image from." msgstr "画像を読み込むファイルを指定して下さい。" #, c-format msgid "" "Could not load image from:\n" "%s" msgstr "" "ここからイメージを読み込めませんでした:\n" "%s" #, c-format msgid "MIME type: %s" msgstr "MIME タイプ: %s" msgid "Picture type:" msgstr "画像タイプ:" msgid "Description:" msgstr "説明:" msgid "(no description)" msgstr "(説明なし)" msgid "Change" msgstr "変更" msgid "Save" msgstr "保存" msgid "Import as Record" msgstr "レコードとしてインポート" msgid "Import as Track No." msgstr "トラック番号としてインポート" msgid "Import as RVA" msgstr "RVA としてインポート" msgid "Add" msgstr "追加" msgid "field:" msgstr "フィールド:" msgid "tag:" msgstr "タグ:" msgid "Audio CD" msgstr "オーディオ CD" msgid "Track:" msgstr "トラック:" msgid "File:" msgstr "ファイル:" msgid "Audio data" msgstr "オーディオデータ" msgid "Format:" msgstr "フォーマット:" msgid "Length:" msgstr "長さ:" msgid "Samplerate:" msgstr "サンプルレート:" #, c-format msgid "%ld Hz" msgstr "%ld Hz" msgid "Channel count:" msgstr "チャンネル数:" msgid "MONO" msgstr "モノラル" msgid "STEREO" msgstr "ステレオ" msgid "Bandwidth:" msgstr "帯域幅:" msgid "Total samples:" msgstr "合計サンプル:" msgid "Mode:" msgstr "モード:" msgid "Type:" msgstr "タイプ:" msgid "Channels:" msgstr "チャンネル:" msgid "Patterns:" msgstr "パターン:" msgid "Samples:" msgstr "サンプル:" msgid "Instruments:" msgstr "楽器:" msgid "Samples" msgstr "サンプル" msgid "Instruments" msgstr "楽器" msgid "Name" msgstr "名前" msgid "STOPPING" msgstr "停止中" msgid "Output:" msgstr "出力:" msgid "No output" msgstr "出力なし" msgid "SRC Type: " msgstr "SRCタイプ: " #, c-format msgid "Loop range: %d-%d%% [%s - %s]" msgstr "ループ範囲: %d-%d%% [%s - %s]" #, c-format msgid "Loop range: %d-%d%%" msgstr "ループ範囲: %d-%d%%" msgid "" "One or more stores in Music Store have been modified.\n" "Do you want to save them before exiting?" msgstr "" "Music Storeの1つ以上のストアが変更されました。\n" "終了前に保存しますか?" msgid "Do not exit" msgstr "終了しない" msgid "Quit" msgstr "終了" #, c-format msgid "Position: %d%%" msgstr "ポジション: %d%%" #, c-format msgid "Mute" msgstr "ミュート" #, c-format msgid "%d dB" msgstr "%d dB" #, c-format msgid "Volume: %s" msgstr "ボリューム: %s" #, c-format msgid "%d%% R" msgstr "%d%% R" #, c-format msgid "%d%% L" msgstr "%d%% L" #, c-format msgid "C" msgstr "C" #, c-format msgid "Balance: %s" msgstr "バランス: %s" msgid "JACK connection lost" msgstr "JACK 接続が失われました" msgid "JACK has either been shutdown or it disconnected Aqualung because it was not fast enough. All you can do now is restart both JACK and Aqualung." msgstr "JACK は十分な速度がないので、シャットダウンされたか Aqualung を切断しました。今すぐ JACK と Aqualung を再起動して下さい。" msgid "Warn me if the Window Manager does not support system tray" msgstr "ウィンドウマネージャがシステムトレイをサポートしない時は警告します" msgid "Aqualung is compiled with system tray support, but the status icon could not be embedded in the notification area. Your desktop may not have support for a system tray, or it has not been configured correctly." msgstr "Aqualung はシステムトレイを有効にしてコンパイルされています。しかし、ステータスアイコンを通知領域に表示できませんでした。お使いのデスクトップは、システムトレイをサポートしていないか、正しく構成されていません。" msgid "Settings" msgstr "設定" msgid "Skin chooser" msgstr "スキン選択" msgid "JACK port setup" msgstr "JACK ポート設定" msgid "Previous song" msgstr "前の曲" msgid "Stop" msgstr "停止" msgid "Next song" msgstr "次の曲" msgid "Play/Pause" msgstr "再生/一時停止" msgid "Play" msgstr "再生" msgid "Pause" msgstr "一時停止" msgid "Repeat current song" msgstr "現在の曲をリピート" msgid "Repeat all songs" msgstr "全ての曲をリピート" msgid "Shuffle songs" msgstr "曲をシャッフル" msgid "Toggle playlist" msgstr "プレイリストを切り替え" msgid "Toggle music store" msgstr "Music Store を切り替え" msgid "Toggle LADSPA patch builder" msgstr "LADSPA パッチビルダを切り替え" msgid "Show Aqualung" msgstr "Aqualung を表示" msgid "Hide Aqualung" msgstr "Aqualung を隠す" msgid "Previous" msgstr "前" msgid "Next" msgstr "次" #, c-format msgid "%.1f MB / %.1f MB" msgstr "%.1f MB / %.1f MB" #, c-format msgid "%d / %d files" msgstr "%d / %d ファイル" #, c-format msgid "%d / %d directories" msgstr "%d / %d ディレクトリ" msgid "Cannot write to selected directory. Please select another directory." msgstr "選択したディレクトリに書き込めません。別のディレクトリを選択して下さい。" msgid "Done" msgstr "完了" msgid "Aborted..." msgstr "中止..." msgid "Please enter directory name." msgstr "ディレクトリ名を入力して下さい。" msgid "Create directory" msgstr "ディレクトリを作成" msgid "Please enter a new name." msgstr "新しい名前を入力して下さい。" msgid "Rename" msgstr "リネーム" #, c-format msgid "" "Directory '%s' will be removed with its entire contents.\n" "\n" "Do you want to proceed?" msgstr "" "ディレクトリ '%s' は全てのコンテンツを含めて削除されます。\n" "\n" "続けますか?" #, c-format msgid "" "File '%s' will be removed.\n" "\n" "Do you want to proceed?" msgstr "" "ファイル '%s' は削除されます。\n" "\n" "続けますか?" msgid "Remove" msgstr "削除" #, c-format msgid " (%.1f MB)" msgstr " (%.1f MB)" #, c-format msgid " (capacity = %.1f MB)" msgstr " (容量 = %.1f MB)" #, c-format msgid " Free space (%.1f MB)" msgstr "空きスペース (%.1f MB)" msgid "" "No suitable iRiver iFP device found.\n" "Perhaps it is unplugged or turned off." msgstr "" "iRiver-iFP に合うデバイスが見つかりません。\n" "たぶん、接続されていないか電源が切れています。" msgid "" "Device is busy.\n" "(Aqualung was unable to claim its interface.)" msgstr "" "デバイスがビジーです。\n" "(Aqualung はそのインターフェースを取得できませんでした。)" msgid "" "Device is not responding.\n" "Try jiggling the handle." msgstr "" "デバイスは応答がありません。\n" "ハンドルを軽く動かして見て下さい。" msgid "Please select a local path." msgstr "ローカルパスを選択して下さい。" msgid "Please select at least one valid song from playlist." msgstr "プレイリストから少なくとも1つ有効な曲を選択して下さい。" #, c-format msgid "" "One song has format unsupported by your player.\n" "\n" "Do you want to proceed?" msgstr "" "1曲はお使いのプレーヤではサポートされていない形式です。\n" "続けますか?" #, c-format msgid "" "%d of %d songs have format unsupported by your player.\n" "\n" "Do you want to proceed?" msgstr "" "%d 中 %d 曲はお使いのプレーヤではサポートされていない形式です。\n" "\n" "続けますか?" #, c-format msgid "" "The selected song has format unsupported by your player.\n" "\n" "Do you want to proceed?" msgstr "" "選択した曲はお使いのプレーヤではサポートされていない形式です。\n" "\n" "続けますか?" #, c-format msgid "" "None of the selected songs has format supported by your player.\n" "\n" "Do you want to proceed?" msgstr "" "お使いのプレーヤでサポートされていない形式の曲は選択されていません。\n" "\n" "続けますか?" msgid "iFP device manager (upload mode)" msgstr "iFP デバイスマネージャ (アップロード モード)" msgid "iFP device manager (download mode)" msgstr "iFP デバイスマネージャ (ダウンロード モード)" msgid "Selected files:" msgstr "選択したファイル:" msgid "Songs info" msgstr "曲情報" msgid "Model:" msgstr "モデル:" msgid "Battery" msgstr "バッテリー" msgid "Free space" msgstr "空きスペース" msgid "Device status" msgstr "デバイス状況" msgid "Size" msgstr "サイズ" msgid "Create a new directory" msgstr "新しいディレクトリを作成" msgid "Remote directory" msgstr "ディレクトリを削除" msgid "Local directory" msgstr "ローカルディレクトリ" msgid "Browse" msgstr "ブラウズ" msgid "File name: " msgstr "ファイル名:" msgid "Current file: " msgstr "現在のファイル:" msgid "Overall: " msgstr "全般:" msgid "Idle" msgstr "待機中" msgid "Transfer progress" msgstr "転送進行状況" msgid "Close window when transfer complete" msgstr "転送完了後、ウィンドウを閉じる" msgid "_Upload" msgstr "アップロード(_U)" msgid "_Download" msgstr "ダウンロード(_D)" msgid "_Abort" msgstr "中止(_A)" msgid "Album" msgstr "アルバム" msgid "Date" msgstr "日付" msgid "Genre" msgstr "ジャンル" msgid "Track No." msgstr "トラック番号" msgid "Comment" msgstr "コメント" msgid "Disc" msgstr "ディスク" msgid "Performer" msgstr "演奏者" msgid "Description" msgstr "説明" msgid "Organization" msgstr "組織" msgid "Location" msgstr "場所" msgid "Contact" msgstr "コンタクト" msgid "License" msgstr "ライセンス" msgid "Copyright" msgstr "著作権" msgid "ISRC" msgstr "ISRC" msgid "Version" msgstr "バージョン" msgid "Subtitle" msgstr "サブタイトル" msgid "Debut Album" msgstr "デビューアルバム" msgid "Publisher" msgstr "出版社" msgid "Conductor" msgstr "指揮者" msgid "Composer" msgstr "作曲者" msgid "Publication Right" msgstr "出版権" msgid "File" msgstr "ファイル" msgid "EAN/UPC" msgstr "EAN/UPC" msgid "ISBN" msgstr "ISBN" msgid "Catalog Number" msgstr "カタログ番号" msgid "Label Code" msgstr "ラベルコード" msgid "Record Date" msgstr "録音日" msgid "Record Location" msgstr "録音場所" msgid "Media" msgstr "メディア" msgid "Index" msgstr "インデックス" msgid "Related" msgstr "関連" msgid "Abstract" msgstr "要約" msgid "Language" msgstr "言語" msgid "Bibliography" msgstr "目録" msgid "Introplay" msgstr "イントロ再生" msgid "BPM" msgstr "BPM" msgid "Encoding Time" msgstr "エンコード時間" msgid "Playlist Delay" msgstr "プレイリスト遅延" msgid "Original Release Time" msgstr "オリジナル リリース時間 " msgid "Release Time" msgstr "リリース時間" msgid "Tagging Time" msgstr "タグ付け時間" msgid "Encoded by" msgstr "エンコード" msgid "Lyricist/Text Writer" msgstr "作詞者/テキストライタ" msgid "File Type" msgstr "ファイルタイプ" msgid "Involved People" msgstr "関係者" msgid "Content Group" msgstr "コンテンツグループ" msgid "Initial key" msgstr "イニシャルキー" msgid "Musician Credits" msgstr "ミュージシャン クレジット" msgid "Mood" msgstr "ムード" msgid "Original Album" msgstr "オリジナルアルバム" msgid "Original Filename" msgstr "オリジナルファイル名" msgid "Original Lyricist" msgstr "オリジナル作詞者" msgid "Original Artist" msgstr "オリジナルアーティスト" msgid "File Owner" msgstr "ファイルのオーナー" msgid "Band/Orchestra" msgstr "バンド/オーケストラ" msgid "Interpreted/Remixed" msgstr "変換/リミックス" msgid "Part Of A Set" msgstr "セットの一部" msgid "Produced" msgstr "作成日時" msgid "Internet Radio Station Name" msgstr "インターネットラジオステーション名" msgid "Internet Radio Station Owner" msgstr "インターネットラジオステーション所有者" msgid "Album Sort Order" msgstr "アルバムの並び替え順序" msgid "Performer Sort Order" msgstr "演奏者の並び替え順序" msgid "Title Sort Order" msgstr "タイトルの並び替え順序" msgid "Software" msgstr "ソフトウェア" msgid "Set Subtitle" msgstr "サブタイトルを設定" msgid "User Defined Text" msgstr "指定のテキストを使う" msgid "Commercial Information" msgstr "コマーシャル情報" msgid "Copyright/Legal Information" msgstr "著作権/法律情報" msgid "Official Audio File Website" msgstr "公式音声ファイルウェブサイト" msgid "Official Artist Website" msgstr "公式アーティストウェブサイト" msgid "Official Audio Source Website" msgstr "公式オーディオソースウェブサイト" msgid "Official Radio Station Website" msgstr "公式ラジオステーションウェブサイト" msgid "Payment" msgstr "支払い" msgid "Publisher's Official Website" msgstr "出版社公式ウェブサイト" msgid "User Defined URL" msgstr "ユーザ指定のURL" msgid "Vendor" msgstr "ベンダー" msgid "ReplayGain Reference Loudness" msgstr "ReplayGain ラウドネス参照" msgid "ReplayGain Track Gain" msgstr "ReplayGain トラックゲイン" msgid "ReplayGain Track Peak" msgstr "ReplayGain トラックピーク" msgid "ReplayGain Album Gain" msgstr "ReplayGain アルバムゲイン" msgid "ReplayGain Album Peak" msgstr "ReplayGain アルバムピーク" msgid "Icy-Name" msgstr "Icy-名" msgid "Icy-Description" msgstr "Icy-説明" msgid "Icy-Genre" msgstr "Icy-ジャンル" msgid "RVA" msgstr "RVA" msgid "Attached Picture" msgstr "添付画像" msgid "Binary Object" msgstr "バイナリ オブジェクト" msgid "NULL" msgstr "何のデータも含まれない" msgid "ID3v1" msgstr "ID3v1" msgid "ID3v2" msgstr "ID3v2" msgid "APE" msgstr "APE" msgid "Ogg Xiph Comments" msgstr "Ogg-Xiph コメント" msgid "FLAC Pictures" msgstr "FLAC 画像" msgid "Musepack ReplayGain" msgstr "Musepack ReplayGain" msgid "Generic StreamMeta" msgstr "汎用ストリームメタ" msgid "MPEG StreamMeta" msgstr "MPEG ストリームメタ" msgid "Module info" msgstr "モジュール情報" msgid "Unknown" msgstr "不明" msgid "Success" msgstr "成功" msgid "Memory allocation error" msgstr "メモリ割り当てエラー" msgid "Unable to open file" msgstr "ファイルを開けません" msgid "No metadata support for this format" msgstr "この形式をサポートするメタデータはありません" msgid "File is not writable" msgstr "ファイルは書き込み可能ではありません" msgid "Invalid 'Track no.' field value" msgstr "無効な 'トラック番号' フィールド値" msgid "Invalid 'Genre' field value" msgstr "無効な 'ジャンル' フィールド値" msgid "Conversion to target charset failed" msgstr "ターゲット文字セットの変換に失敗" msgid "Internal error" msgstr "内部エラー" msgid "Unknown error" msgstr "不明なエラー" msgid "Other" msgstr "その他" msgid "File icon (32x32 PNG)" msgstr "ファイルアイコン (32x32 PNG)" msgid "File icon (other)" msgstr "ファイルアイコン (その他)" msgid "Front cover" msgstr "表紙" msgid "Back cover" msgstr "裏表紙" msgid "Leaflet page" msgstr "リーフレットページ" msgid "Album image" msgstr "アルバム画像" msgid "Lead artist/performer" msgstr "リードアーティスト/演奏者" msgid "Artist/performer" msgstr "アーティスト/演奏者" msgid "Band/orchestra" msgstr "バンド/オーケストラ" msgid "Lyricist/text writer" msgstr "作詞家/テキストライター" msgid "Recording location/studio" msgstr "録音場所/スタジオ" msgid "During recording" msgstr "レコーディング中" msgid "During performance" msgstr "演奏中" msgid "Movie/video screen capture" msgstr "ムービー/ビデオスクリーンキャプチャ" msgid "A large, coloured fish" msgstr "大きな色付きの魚" msgid "Illustration" msgstr "イラスト" msgid "Band/artist logotype" msgstr "バンド/アーティストロゴタイプ" msgid "Publisher/studio logotype" msgstr "出版社/スタジオロゴタイプ" msgid "Music Store" msgstr "Music Store" msgid "Search..." msgstr "検索..." msgid "Collapse all items" msgstr "全てのアイテムを折りたたむ" msgid "Edit item..." msgstr "アイテムを編集..." msgid "Add item..." msgstr "アイテムを追加..." msgid "Remove item..." msgstr "アイテムを削除..." msgid "Save all stores" msgstr "全てのストアを保存" msgid "Create empty store..." msgstr "空のストアを作成..." msgid "*Music Store" msgstr "*Music Store" #, c-format msgid "Do you want to save store \"%s\" before removing from Music Store?" msgstr "Music Store から削除する前に、ストア \"%s\" を保存しますか?" msgid "You will need to restart Aqualung for the following changes to take effect:" msgstr "次の変更を有効にするには Aqualung を再起動する必要があります:" msgid "Select a font..." msgstr "フォントを選択..." msgid "Disable skin support" msgstr "スキンサポートを無効" msgid "rw" msgstr "rw" msgid "r" msgstr "r" msgid "unreachable" msgstr "到達不能" msgid "Please select a Programable Title Format File." msgstr "プログラム可能なタイトル形式のファイルを選択して下さい。" msgid "Please select a Music Store database." msgstr "Music Store データベースを選択して下さい。" msgid "Paths must either be absolute or starting with a tilde." msgstr "パスは絶対パスかチルダ付きで始まらなければなりません。" msgid "The specified store has already been added to the list." msgstr "指定のストアは既にリストに追加されています。" #, c-format msgid "" "\n" "The template string you enter here will be used to construct a single title line from an Artist, a Record and a Track name. These are denoted by %%%%a, %%%%r and %%%%t, respectively.\n" msgstr "" "\n" "ここに入力するテンプレート文字列は、アーティスト、レコード、トラック名から1つのタイトル行を構成するために使われます。それらは個々に %%%%a, %%%%r と %%%%t, で示されます。\n" msgid "" "\n" "The file you enter/choose here will set the Lua program to use to format the title. See the Aqualung manual for details. Here is a quick example of what you can use in the file:\n" "\n" "function playlist_title()\n" " return m('artist') .. '-' .. m('title') .. ' (' .. m('album') .. ') (' .. i('filename') .. ')'\n" "end" msgstr "" "\n" "ここで入力/選択をしたファイルはタイトルをフォーマットするために使う Lua プログラムを設定します。詳細は Aqualung マニュアルを確認して下さい。以下はファイルで使える簡単なサンプルです:\n" "\n" "function playlist_title()\n" " return m('artist') .. '-' .. m('title') .. ' (' .. m('album') .. ') (' .. i('filename') .. ')'\n" "end" msgid "" "\n" "The string you enter here will be parsed as a command line before parsing the actual command line parameters. What you enter here will act as a default setting and may or may not be overridden from the 'real' command line.\n" "\n" "Example: enter '-o alsa -R' below to use ALSA output running realtime as a default.\n" msgstr "" "\n" "ここで入力する文字列は、実際のコマンドラインパラメータを解析する前のコマンドラインとして解析されます。ここで入力したものは、初期設定として作動し、「本当の」コマンドラインから上書きされるか、されないかも知れません。\n" "\n" "例: リアルタイムで実行している ALSA 出力をデフォルトで使うには、下に '-o alsa -R' と入力します。\n" msgid "" "Paths must either be absolute or starting with a tilde, which will be expanded to the user's home directory.\n" "\n" "Drag and drop entries in the list to set the store order in the Music Store." msgstr "" "パスは絶対パスかチルダ付きで始まらなければなりません。そしてユーザのホームディレクトリに展開されます。\n" "\n" "Music Store にストア順序を設定するにはエントリをリストにドラッグアンドドロップして下さい。" msgid "" "\n" "Set the drive speed for CD playing in CD-ROM speed units. One speed unit equals to 176 kBps raw data reading speed. Warning: not all drives honor this setting.\n" "\n" "Lower speed usually means less drive noise. However, when using Paranoia error correction modes for increased accuracy, generally much larger speeds are required to prevent buffer underruns (and thus audible drop-outs).\n" "\n" "Please note that these settings do not apply to CD Ripping, which always happens with maximum available speed and with error correction modes manually set before every run." msgstr "" "\n" "CD のドライブ速度は、再生している CD-ROM の速度単位に設定して下さい。速度の1単位は、176kBps 生データの読み出し速度に等しいです。警告: 全てのドライブが、この設定を守るというわけではありません。\n" "\n" "通常、速度が低いとドライブのノイズが減ります。しかし、精度を増すために Paranoia エラー訂正モードを使う場合、一般的に、バッファアンダーランを防ぐため、より高い速度が要求されます (そして、このような可聴ドロップアウト)。\n" "\n" "これらの設定は CD リッピングに適用されない点に注意して下さい。CD リッピングでは毎回実行する前に、利用できる最高速度やエラー訂正モードを手動で設定します。" msgid "" "\n" "Most drives let Aqualung know when a CD has been inserted or removed by providing a 'media changed' flag. However, some drives don't set this flag properly, and thus it may happen that a newly inserted CD remains unnoticed to Aqualung. In such cases, enabling this option should help." msgstr "" "\n" "大部分のドライブは、 CD が挿入されたり、取り外された時、 Aqualung に「メディアが交換されたこと」を通知します。しかし、いくつかのドライブはこの通知フラグを適切に設定しないため、時々、Aqualung は新しく挿入された CD を認識しないことがあります。そのような場合、このオプションを有効にすると軽減されるでしょう。" msgid "" "\n" "Here you should enter a comma-separated list of domains\n" "that should be accessed without using the proxy set above.\n" "Example: localhost, .localdomain, .my.domain.com" msgstr "" "\n" "ここでは、上で設定したプロキシを介さずにアクセスする\n" "ドメインリスト(カンマ区切り)を入力しなければなりません。\n" "例:localhost, .localdomain, .my.domain.com" msgid "Embed playlist into main window" msgstr "プレイリストをメインウィンドウに埋め込む" msgid "Enable systray" msgstr "システムトレイを有効にする" msgid "Do nothing" msgstr "何もしない" msgid "Change volume" msgstr "音量の変更" msgid "Change balance" msgstr "バランスの変更" msgid "Change song position" msgstr "再生位置の変更" msgid "Change current song" msgstr "曲の変更" msgid "Left button" msgstr "左ボタン" msgid "Middle button" msgstr "中央ボタン" msgid "Right button" msgstr "右ボタン" msgid "Button" msgstr "ボタン" msgid "Left and right mouse buttons are reserved." msgstr "右ボタンと左ボタンは予約されています。" msgid "This button is already assigned." msgstr "このボタンはすでに割り当てられています。" msgid "Add mouse button command" msgstr "マウスボタンにコマンドを追加" msgid "Mouse button" msgstr "マウスボタン" msgid "Click here to set mouse button" msgstr "マウスボタンを設定するにはここをクリック" msgid "Command" msgstr "コマンド" msgid "Main window" msgstr "メインウィンドウ" msgid "Disable control buttons relief" msgstr "コントロールボタンの装飾を無効" msgid "Combine play and pause buttons" msgstr "再生ボタンと一時停止ボタンを一体化" msgid "Keep main window always on top" msgstr "メインウィンドウを常に一番上にする" msgid "Show song name in the main window's title" msgstr "メインウィンドウのタイトルに曲名を表示する" msgid "Title Format" msgstr "タイトル形式" msgid "Programmable title format file" msgstr "プログラム可能なタイトル形式ファイル" msgid "Systray" msgstr "システムトレイ" msgid "Start minimized" msgstr "最小化した状態で開始する" msgid "Play/Stop song" msgstr "曲の再生/停止" msgid "Play/Pause song" msgstr "曲の再生/一時停止" msgid "Mouse wheel" msgstr "マウスホイール" msgid "Vertical mouse wheel:" msgstr "垂直マウスホイール:" msgid "Horizontal mouse wheel:" msgstr "水平マウスホイール:" msgid "Mouse buttons" msgstr "マウスボタン" msgid "Miscellaneous" msgstr "その他" msgid "Implicit command line" msgstr "暗黙的なコマンドライン" msgid "Cover art" msgstr "ジャケット画像" msgid "Default cover width:" msgstr "デフォルトカバー幅:" msgid "50 pixels" msgstr "50 ピクセル" msgid "100 pixels" msgstr "100 ピクセル" msgid "200 pixels" msgstr "200 ピクセル" msgid "300 pixels" msgstr "300 ピクセル" msgid "use browser window width" msgstr "ブラウザのウィンドウ幅を使う" msgid "Do not magnify images with smaller width" msgstr "より小さい幅で画像を拡大しない" msgid "Show cover thumbnail for Music Store tracks only" msgstr "Music Store トラックのジャケットサムネイルだけを表示" msgid "Don't show cover thumbnail in the main window" msgstr "メインウィンドウにジャケットのサムネイルを表示しない" msgid "Enable tooltips" msgstr "ツールチップを有効" msgid "Simple view in LADSPA patch builder" msgstr "LADSPA パッチビルダでシンプル表示" msgid "United windows minimization" msgstr "結合したウィンドウの最小化" msgid "Show hidden files and directories in file choosers" msgstr "ファイル選択画面で隠しファイル/ディレクトリを表示する" msgid "Show tags tab first in the file info dialog" msgstr "ファイル情報ダイアログで最初にタグタブを表示" msgid "Playlist" msgstr "プレイリスト" msgid "Put control buttons at the bottom of playlist" msgstr "コントロールボタンをプレイリストの一番下に置く" msgid "Save and restore the playlist on exit/startup" msgstr "終了/起動時にプレイリストを保存/復元" msgid "Save playlist periodically [min]:" msgstr "プレイリストを定期的に保存 [分]:" msgid "Album mode is the default when adding entire records" msgstr "全レコードを追加する時はアルバムモードがデフォルト" msgid "Always show the tab bar" msgstr "常にタブバーを表示" msgid "Show close button in tab" msgstr "タブに閉じるボタンを表示" msgid "When shuffling, records added in Album mode are played in order" msgstr "シャッフルの時は、レコードはアルバムモードに追加された順に再生" msgid "Enable statusbar" msgstr "ステータスバーを有効" msgid "Enable statusbar in playlist" msgstr "プレイリストにステータスバーを有効" msgid "Show soundfile size in statusbar" msgstr "ステータスバーに音声ファイルのサイズを表示" msgid "Show RVA values" msgstr "RVA 値を表示" msgid "Show track lengths" msgstr "トラック長を表示" msgid "Show active track name in bold" msgstr "アクティブなトラック名を太字で表示" msgid "Automatically roll to active track" msgstr "自動的にアクティブなトラックへ移動" msgid "Enable rules hint" msgstr "ルールヒントを有効" msgid "Playlist column order" msgstr "列順プレイリスト" msgid "" "Drag and drop entries in the list below \n" "to set the column order in the Playlist." msgstr "" "プレイリストの列順を設定するには\n" "エントリを下のリストにドラッグアンドドロップしてください。" msgid "Column" msgstr "列" msgid "Track titles" msgstr "トラックタイトル" msgid "RVA values" msgstr "RVA 値" msgid "Track lengths" msgstr "トラックの長さ" msgid "Hide comment pane" msgstr "コメント欄を隠す" msgid "Hide the Music Store comment pane" msgstr "Music Store のコメント欄を隠す" msgid "Enable toolbar" msgstr "ツールバーを有効" msgid "Enable toolbar in Music Store" msgstr "Music Store でツールバーを有効" msgid "Enable statusbar in Music Store" msgstr "Music Store でステータスバーを有効" msgid "Expand Stores on startup" msgstr "起動時にストアを展開" msgid "Enable tree node icons" msgstr "ツリーノードアイコンを有効" msgid "Enable Music Store tree node icons" msgstr "Music Store ツリーノードアイコンを有効" msgid "Ask for confirmation when removing items" msgstr "アイテムを削除する時に確認すを要求" msgid "Paths to Music Store databases" msgstr "Music Store データベースへのパス" msgid "Path" msgstr "パス" msgid "Access" msgstr "アクセス" msgid "Refresh" msgstr "更新" msgid "DSP" msgstr "DSP (デジタル信号処理)" msgid "LADSPA plugin processing" msgstr "LADSPA プラグイン処理" msgid "Pre Fader (before Volume & Balance)" msgstr "プリフェーダ (AUX 出力を前から音量コントロール)" msgid "Post Fader (after Volume & Balance)" msgstr "ポストフェーダ (AUX 出力を後ろから音量コントロール)" msgid "" "Aqualung is compiled without LADSPA plugin support.\n" "See the About box and the documentation for details." msgstr "" "Aqualung は LADSPA プラグインサポートなしでコンパイルされています。\n" "詳細は「このソフトについて」とドキュメントをご覧下さい。" msgid "Sample Rate Converter type" msgstr "サンプルレート変換形式" msgid "" "Aqualung is compiled without Sample Rate Converter support.\n" "See the About box and the documentation for details." msgstr "" "Aqualung はサンプルレート変換サポートなしでコンパイルされています。\n" "詳細は「このソフトについて」とドキュメントをご覧下さい。" msgid "Playback RVA" msgstr "RVA 再生" msgid "Enable playback RVA" msgstr "RVA 再生を有効" msgid "Listening environment:" msgstr "リスニング環境:" msgid "Audiophile" msgstr "オーディオファン(Hi-Fi愛好家)" msgid "Living room" msgstr "居間" msgid "Office" msgstr "オフィス" msgid "Noisy workshop" msgstr "やかましい工場" msgid "Reference volume [dBFS] :" msgstr "基準音量 [dBFS] :" msgid "Steepness [dB/dB] :" msgstr "急激度 [dB/dB] :" msgid "RVA for Unmeasured Files [dB] :" msgstr "無制限ファイルの RVA [dB] :" msgid "Apply averaged RVA to tracks of the same record" msgstr "同じレコードのトラックに平均 RVA を適用" msgid "Drop statistical aberrations based on" msgstr "統計的収差を下げる" #, no-c-format msgid "% of standard deviation" msgstr "標準偏差の % " msgid "Linear threshold [dB]" msgstr "線形しきい値 [dB]" msgid "Linear threshold [dB] :" msgstr "線形しきい値 [dB] :" #, no-c-format msgid "% of standard deviation :" msgstr "標準偏差の % :" msgid "ReplayGain tag to use (with fallback to the other): " msgstr "使用する ReplayGain タグ (他にフォールバック): " msgid "Replaygain_track_gain" msgstr "Replaygain_track_gain" msgid "Replaygain_album_gain" msgstr "Replaygain_album_gain" msgid "Adding files to Playlist" msgstr "ファイルをプレイリストに追加" msgid "" "Use basename only instead of full path\n" "if no metadata is available." msgstr "" "メタデータが利用できなければ\n" "フルパスの変わりにベースネームだけを使います。" msgid "Metadata editor (File info dialog)" msgstr "メタデータエディタ (ファイル情報ダイアログ)" msgid "" "When adding new frames, try to set their contents\n" "from another tag's equivalent frame." msgstr "" "新しいフレームを追加するとき、別タグの同じフレームから\n" "コンテンツの設定を試して下さい。" msgid "Batch update & encode (mass tagger, CD ripper, file export)" msgstr "バッチ更新とエンコード (mass tagger、CD リッパ、ファイルエクスポート)" msgid "Tags to add when creating or updating MPEG audio files:" msgstr "MPEG オーディオファイルの作成、更新の時に追加するタグ:" msgid "" "Note: pre-existing tags will be updated even though they\n" "might not be checked here." msgstr "メモ: これまでのタグはここでチェックされなくても更新されます。" msgid "CD Audio" msgstr "CD オーディオ" msgid "CD drive speed:" msgstr "CD ドライブ速度:" msgid "\tMaximum number of retries:" msgstr "\tリトライの最大数:" msgid "Force TOC re-read on every drive scan" msgstr "ドライブスキャン毎に強制的に TOC を再読み込み" msgid "Automatically add CDs to Playlist" msgstr "CD をプレイリストに自動的に追加" msgid "Automatically remove CDs from Playlist" msgstr "CD をプレイリストから自動的に削除" msgid "CDDB server:" msgstr "CDDB サーバ:" msgid "Connection timeout [sec]:" msgstr "接続タイムアウト [秒]:" msgid "Email address for submission:" msgstr "送信用メールアドレス:" msgid "Local CDDB directory:" msgstr "ローカル CDDB ディレクトリ:" msgid "Use the local database only" msgstr "ローカルデータベースだけを使う" msgid "Protocol for querying (direct connection only):" msgstr "問い合わせを行うプロトコル (直接接続のみ):" msgid "CDDBP (port 888)" msgstr "CDDBP (ポート 888)" msgid "HTTP (port 80)" msgstr "HTTP (ポート 80)" msgid "Internet" msgstr "インターネット" msgid "Direct connection to the Internet" msgstr "インターネットに直接接続" msgid "Connect via HTTP proxy" msgstr "HTTP プロキシ経由で接続" msgid "Proxy settings" msgstr "プロキシ設定" msgid "Proxy host:" msgstr "プロキシホスト:" msgid "Port:" msgstr "ポート:" msgid "No proxy for:" msgstr "プロキシなし:" msgid "Timeout for socket I/O:" msgstr "ソケット I/O のタイムアウト:" msgid "seconds" msgstr "秒" msgid "Appearance" msgstr "外観" msgid "Override skin settings" msgstr "スキンの設定を無視する" msgid "Fonts" msgstr "フォント" msgid "Playlist: " msgstr "プレイリスト: " msgid "Music Store: " msgstr "Music Store: " msgid "Big timer: " msgstr "大きいタイマ: " msgid "Small timers: " msgstr "小さいタイマ: " msgid "Song title: " msgstr "曲のタイトル: " msgid "Song info: " msgstr "曲の情報: " msgid "Statusbar: " msgstr "ステータスバー: " msgid "Colors" msgstr "色" msgid "Song in playlist: " msgstr "プレイリストの曲: " msgid "Active song in playlist: " msgstr "プレイリストのアクティブな曲: " msgid "Error in title format string" msgstr "タイトル形式文字列にエラー" msgid "(Untitled)" msgstr "(タイトルなし)" #, c-format msgid " (%d/%d)" msgstr " (%d/%d)" msgid "Select files" msgstr "ファイルを選択" msgid "Select directory" msgstr "ディレクトリを選択" msgid "Add URL" msgstr "URL を追加" msgid "URL:" msgstr "URL:" msgid "Please specify the file to save the playlist to." msgstr "プレイリストを保存するファイルを指定して下さい。" msgid "Please specify the file to load the playlist from." msgstr "プレイリストを読み込むファイルを指定して下さい。" msgid "" "Playback RVA is currently disabled.\n" "Do you want to enable it now?" msgstr "" "再生 RVA は現在無効です。\n" "今すぐ有効にしますか?" msgid "counting..." msgstr "カウント中..." msgid "track" msgstr "トラック" msgid "tracks" msgstr "トラック" msgid "Rename playlist" msgstr "プレイリストをリネーム" msgid "Name:" msgstr "名前:" msgid "New tab" msgstr "新しいタブ" msgid "Close tab" msgstr "タブを閉じる" msgid "Undo close tab" msgstr "タブを閉じるを元に戻す" msgid "Close other tabs" msgstr "他のタブを閉じる" msgid " Selected: " msgstr "選択: " msgid "Total: " msgstr "合計: " msgid "Add files" msgstr "ファイルを追加" msgid "" "Add files to playlist\n" "(Press right mouse button for menu)" msgstr "" "ファイルをプレイリストに追加\n" "(マウスの右ボタンを押すとメニュー)" msgid "Select all" msgstr "全て選択" msgid "" "Select all songs in playlist\n" "(Press right mouse button for menu)" msgstr "" "プレイリストの全ての曲を選択\n" "(マウスの右ボタンを押すとメニュー)" msgid "Remove selected" msgstr "選択を削除" msgid "" "Remove selected songs from playlist\n" "(Press right mouse button for menu)" msgstr "" "プレイリストから選択した曲を削除\n" "(マウスの右ボタンを押すとメニュー)" msgid "Add directory" msgstr "ディレクトリを追加" msgid "Select none" msgstr "何も選択しない" msgid "Invert selection" msgstr "選択を反転" msgid "Remove all" msgstr "全て削除" msgid "Remove dead" msgstr "存在しないものを削除" msgid "Cut selected" msgstr "選択範囲を切り取る" msgid "Save playlist" msgstr "プレイリストを保存" msgid "Save all playlists" msgstr "全てのプレイリストを保存" msgid "Load playlist in new tab" msgstr "プレイリストを新しいタブで読み込む" msgid "Load playlist" msgstr "プレイリストを読み込む" msgid "Enqueue playlist" msgstr "待ちプレイリスト" msgid "Send to iFP device" msgstr "iFP デバイスに送信" msgid "Calculate RVA" msgstr "RVA を計算" msgid "Separate" msgstr "分離" msgid "Average" msgstr "平均" msgid "Reread file metadata" msgstr "ファイルのメタデータを再読み込み" msgid "File info..." msgstr "ファイル情報..." msgid "Roll to active song" msgstr "アクティブな曲に移動" msgid "Stop adding files" msgstr "ファイルの追加を中止" msgid "Files selected for removal" msgstr "削除選択したファイル" msgid "Remove files" msgstr "ファイルを削除" msgid "" "The selected files will be deleted from the filesystem. No recovery will be possible after this operation.\n" "\n" "Do you want to proceed?" msgstr "" "選択したファイルはファイルシステムから削除されます。この操作後はリカバリできません。\n" "\n" "続けますか?" #, c-format msgid "Unable to remove %d file." msgstr "%d ファイルを削除する事はできません。" #, c-format msgid "Unable to remove %d files." msgstr "%d ファイルを削除する事はできません。" msgid "LADSPA patch builder" msgstr "LADSPA パッチビルダ" msgid "Available plugins" msgstr "利用できるプラグイン" msgid "ID" msgstr "ID" msgid "Category" msgstr "カテゴリ" msgid "Inputs" msgstr "入力" msgid "Outputs" msgstr "出力" msgid "Running plugins" msgstr "プラグインを実行" msgid "_Configure" msgstr "設定(_C)" msgid "Enable all plugins" msgstr "全てのプラグインを有効" msgid "Disable all plugins" msgstr "全てのプラグインを無効" msgid "Invert current state" msgstr "現在の状況を反転" msgid "Clear list" msgstr "リストをクリア" msgid "Untitled" msgstr "タイトルなし" msgid "JACK Port Setup" msgstr "JACK ポート設定" msgid "Rescan" msgstr "再スキャン" msgid "Available connections" msgstr "利用できる接続" msgid "Clear connections" msgstr "接続をクリア" msgid " out L" msgstr " 左外" msgid " out R" msgstr " 右外" msgid "Search the Music Store" msgstr "Music Store を検索" msgid "Key: " msgstr "キー: " msgid "Case sensitive" msgstr "大文字小文字を区別" msgid "Exact matches only" msgstr "完全一致のみ" msgid "Select first and close window" msgstr "最初に選択してからウィンドウを閉じる" msgid "Search in:" msgstr "検索:" msgid "Artist names" msgstr "アーティスト名" msgid "Record titles" msgstr "レコードタイトル" msgid "Comments" msgstr "コメント" msgid "Search" msgstr "検索" msgid "Search the Playlist" msgstr "プレイリストを検索" msgid "Available skins" msgstr "利用できるスキン" msgid "Drive info" msgstr "ドライブ情報" msgid "Device path:" msgstr "デバイスのパス:" msgid "Vendor:" msgstr "ベンダー:" msgid "Revision:" msgstr "リビジョン:" msgid "" "The information below is reported by the drive, and\n" "may not reflect the actual capabilities of the device." msgstr "" "以下の情報はドライブから報告されたものです。\n" "しかし実際のデバイスの機能を反映していないかもしれません。" msgid "Eject" msgstr "イジェクト" msgid "Close tray" msgstr "トレイを閉じる" msgid "Disable manual eject" msgstr "手動イジェクトを無効" msgid "Select juke-box disc" msgstr "ジュークボックスディスクを選択" msgid "Set drive speed" msgstr "ドライブ速度を設定" msgid "Detect media change" msgstr "メディアの変更を検出" msgid "Read multiple sessions" msgstr "マルチセッションを読み込む" msgid "Hard reset device" msgstr "デバイスをハードリセット" msgid "Reading" msgstr "読み込み" msgid "Play CD Audio" msgstr "CD オーディオを再生" msgid "Read CD-DA" msgstr "CD-DA を読み込む" msgid "Read CD+G" msgstr "CD+G を読み込む" msgid "Read CD-R" msgstr "CD-R を読み込む" msgid "Read CD-RW" msgstr "CD-RW を読み込む" msgid "Read DVD-R" msgstr "DVD-R を読み込む" msgid "Read DVD+R" msgstr "DVD+R を読み込む" msgid "Read DVD-RW" msgstr "DVD-RW を読み込む" msgid "Read DVD+RW" msgstr "DVD+RW を読み込む" msgid "Read DVD-RAM" msgstr "DVD-RAM を読み込む" msgid "Read DVD-ROM" msgstr "DVD-ROM を読み込む" msgid "C2 Error Correction" msgstr "C2 エラー訂正" msgid "Read Mode 2 Form 1" msgstr "Mode 2 Form 1 を読み込む" msgid "Read Mode 2 Form 2" msgstr "Mode 2 Form 2 を読み込む" msgid "Read MCN" msgstr "MCN を読み込む" msgid "Read ISRC" msgstr "ISRC を読み込む" msgid "Writing" msgstr "書き込み中" msgid "Write CD-R" msgstr "CD-R に書き込む" msgid "Write CD-RW" msgstr "CD-RW に書き込む" msgid "Write DVD-R" msgstr "DVD-R に書き込む" msgid "Write DVD+R" msgstr "DVD-R に書き込む" msgid "Write DVD-RW" msgstr "DVD-RW に書き込む" msgid "Write DVD+RW" msgstr "DVD+RW に書き込む" msgid "Write DVD-RAM" msgstr "DVD-RAM に書き込む" msgid "Mount Rainier" msgstr "マウント レーニア (Mount Rainier)" msgid "Burn Proof" msgstr "バッファーアンダーラン防止 (Burn Proof)" msgid "Disc info" msgstr "ディスク情報" msgid "This CD does not contain CD-Text information." msgstr "この CD は CD テキスト情報を含んでいません。" msgid "drive" msgstr "ドライブ" msgid "drives" msgstr "ドライブ" msgid "record" msgstr "レコード" msgid "records" msgstr "レコード" msgid "Add to playlist" msgstr "プレイリストに追加" msgid "Add to playlist (Album mode)" msgstr "プレイリストに追加 (アルバムモード)" msgid "CDDB query for this CD..." msgstr "この CD を CDDB に問い合わせ..." msgid "Submit CD to CDDB database..." msgstr "CD を CDDB データベースに送信..." msgid "Rip CD..." msgstr "CD をリッピング..." msgid "Disc info..." msgstr "ディスク情報..." msgid "Drive info..." msgstr "ドライブ情報..." msgid "Comments:" msgstr "コメント:" msgid "Please select the xml file for this store." msgstr "ストア用にxmlファイルを選択して下さい。" msgid "Create empty store" msgstr "空のストアを作成" msgid "Visible name:" msgstr "表示名:" msgid "Edit Store" msgstr "ストアを編集" msgid "Use relative paths in store file" msgstr "ストアファイルに相対パスを使う" msgid "Add Artist" msgstr "アーティストを追加" msgid "Name to sort by:" msgstr "並び替える名前:" msgid "Edit Artist" msgstr "アーティストを編集" msgid "Please select the audio files for this record." msgstr "レコード用の音声ファイルを選択して下さい。" msgid "Add Record" msgstr "レコードを追加" msgid "Auto-create tracks from these files:" msgstr "次のファイルからトラックを自動作成:" msgid "_Add files..." msgstr "ファイルを追加(_A)..." msgid "Edit Record" msgstr "レコードを編集" msgid "Please select the audio file for this track." msgstr "このトラックのオーディオファイルを選択して下さい。" msgid "Add Track" msgstr "トラックを追加" msgid "Edit Track" msgstr "トラックを編集" msgid "Duration:" msgstr "演奏時間:" #, c-format msgid "Unmeasured" msgstr "無制限" msgid "Volume level:" msgstr "ボリュームレベル:" msgid "Use manual RVA value [dB]" msgstr "マニュアル RVA 値を使う [dB]" #, c-format msgid "Really remove \"%s\" from the Music Store?" msgstr "Music Store から本当に \"%s\" を削除しますか?" msgid "Stop adding songs" msgstr "曲の追加を中止" #, c-format msgid "" "The store '%s' already exists.\n" "Add it on the Settings/Music Store tab." msgstr "" "ストア '%s' は既に存在します。\n" "それを設定/Music Store タブに追加します。" #, c-format msgid "Really remove store \"%s\" from the Music Store?" msgstr "Music Store から本当にストア \"%s\" を削除しますか?" msgid "Remove Store" msgstr "ストアを削除" msgid "Do you want to save the store before removing?" msgstr "削除する前にストアを保存しますか?" msgid "Remove Artist" msgstr "アーティストを削除" msgid "Remove Record" msgstr "レコードを削除" msgid "Remove Track" msgstr "トラックを削除" msgid "Update file metadata" msgstr "ファイルメタデータを更新" msgid "Track name" msgstr "トラック名" msgid "Track comment" msgstr "トラックコメント" msgid "Track number" msgstr "トラック番号" msgid "Failed to set metadata for the following files:" msgstr "以下のファイルのメタデータ設定に失敗:" msgid "Filename" msgstr "ファイル名" msgid "Reason" msgstr "理由" msgid "(no comment)" msgstr "(コメントなし)" msgid "artist" msgstr "アーティスト" msgid "artists" msgstr "アーティスト" #, c-format msgid "File \"%s\" does not exist or your write permission has been withdrawn. Check if the partition containing the store file has been unmounted." msgstr "ファイル \"%s\" は存在していないか、書き込みができません。storeファイルを含むパーティションが既にアンマウントされてないかチェックして下さい" msgid "Build / Update store from filesystem..." msgstr "ファイルシステムからストアを、ビルド / 更新..." msgid "Edit store..." msgstr "ストアを編集..." msgid "Export store..." msgstr "ストアをエクスポート..." msgid "Save store" msgstr "ストアを保存" msgid "Remove store" msgstr "ストアを削除" msgid "Add new artist to this store..." msgstr "このストアに新しいアーティストを追加..." msgid "Calculate volume (recursive)" msgstr "ボリュームを計算 (rekursiv)" msgid "Unmeasured tracks only" msgstr "無制限トラックだけ" msgid "All tracks" msgstr "全てのトラック" msgid "Batch-update file metadata..." msgstr "ファイルメタデータをバッチ更新..." msgid "Add new artist..." msgstr "新しいアーティストを追加..." msgid "Edit artist..." msgstr "アーティストを編集..." msgid "Export artist..." msgstr "アーティストをエクスポート..." msgid "Remove artist" msgstr "アーティストを削除" msgid "Add new record to this artist..." msgstr "このアーティストに新しいレコードを追加..." msgid "Add new record..." msgstr "新しいレコードを追加..." msgid "Edit record..." msgstr "レコードを編集..." msgid "Export record..." msgstr "レコードをエクスポート..." msgid "Remove record" msgstr "レコードを削除" msgid "Add new track to this record..." msgstr "このレコードに新しいトラックを追加..." msgid "CDDB query for this record..." msgstr "このレコードのCDDB問い合わせ..." msgid "Submit record to CDDB database..." msgstr "CDDBデータベースにレコードを送信..." msgid "Add new track..." msgstr "新しいトラックを追加..." msgid "Edit track..." msgstr "トラックを編集..." msgid "Export track..." msgstr "トラックをエクスポート..." msgid "Remove track" msgstr "トラックを削除" msgid "Calculate volume" msgstr "ボリュームを計算" msgid "Only if unmeasured" msgstr "無制限の時だけ" msgid "In any case" msgstr "どんな場合でも" msgid "Update file metadata..." msgstr "ファイルメタデータを更新..." msgid "Please select the download directory for this podcast." msgstr "このポッドキャストのダウンロードディレクトリを選択して下さい。" msgid "Subscribe to new feed" msgstr "新しいフィードを購読" msgid "Edit feed settings" msgstr "フィード設定を編集" msgid "Podcast URL:" msgstr "ポッドキャストURL:" msgid "Download directory:" msgstr "ディレクトリをダウンロード:" msgid "Auto-check interval [hour]:" msgstr "自動チェックの間隔 [時間]:" msgid "" "Automatic update has been disabled for all feeds\n" "in the Podcasts store popup menu." msgstr "" "ポッドキャストストアポップアップメニューの\n" "全てのフィードの自動更新は無効です。" msgid "Limits" msgstr "限度" msgid "Maximum number of items:" msgstr "アイテムの最大数:" msgid "Remove older items [day]:" msgstr "古いアイテムを削除 [日]:" msgid "Maximum space to use [MB]:" msgstr "使用する最大容量 [MB]:" msgid "Podcasts" msgstr "ポッドキャスト" msgid "Updating..." msgstr "更新中..." msgid "Delete downloaded items from the filesystem" msgstr "ファイルシステムからダウンロードしたアイテムを削除" msgid "Remove feed" msgstr "フィードを削除" #, c-format msgid "Really remove '%s' from the Music Store?" msgstr "本当に Music Store から '%s'を削除しますか?" msgid "Reorder feeds" msgstr "フィードを並び替え" msgid "" "Drag and drop entries in the list\n" "to set the feed order in the Music Store." msgstr "" "Music Store のフィード順を設定するには\n" "リストにエントリをドラッグアンドドロップ。" #, c-format msgid "Downloading %d/%d (%d%%) ..." msgstr "%d/%d (%d%%) をダウンロード中..." msgid "item" msgstr "アイテム" msgid "items" msgstr "アイテム" msgid "new item" msgstr "新しいアイテム" msgid "new items" msgstr "新しいアイテム" msgid "feed" msgstr "フィード" msgid "feeds" msgstr "フィード" msgid "Export item..." msgstr "アイテムをエクスポート..." msgid "Add all items to playlist" msgstr "プレイリストに全てのアイテムを追加" msgid "Add all items to playlist (Album mode)" msgstr "プレイリストに全てのアイテムを追加 (アルバムモード)" msgid "Add new items to playlist" msgstr "プレイリストに新しいアイテムを追加" msgid "Add new items to playlist (Album mode)" msgstr "プレイリストに新しいアイテムを追加 (アルバムモード)" msgid "Edit feed" msgstr "フィードを編集" msgid "Export all items..." msgstr "全てのアイテムをエクスポート..." msgid "Export new items..." msgstr "新しいアイテムをエクスポート..." msgid "Update feed" msgstr "フィードを更新" msgid "Abort ongoing update" msgstr "進行中の更新を中止" msgid "Update all feeds" msgstr "全てのフィードを更新" msgid "Automatically update feeds" msgstr "フィードを自動的に更新" msgid "Unexpected end of string after '?'." msgstr "'?' の後に予期しない文字列の終わりです。" msgid "Expected '}' after '{', but end of string found." msgstr "'{' の後に '}' が必要です。しかし文字列の終わりが見つかりました。" #, c-format msgid "Unknown conversion type character found after '%%%%'." msgstr "'%%%%' の後に不明な変換タイプ文字が見つかりました。" msgid "Unknown conversion type character found after '?'." msgstr "'?' の後に不明な変換タイプ文字が見つかりました。" msgid "day" msgstr "日" msgid "days" msgstr "日" msgid "All Files" msgstr "全てのファイル" msgid "Extended Title Format Files (*.lua)" msgstr "拡張タイトルフォーマットファイル (*.lua)" msgid "Music Store Files (*.xml)" msgstr "Music Store ファイル (*.xml)" msgid "Aqualung playlist (*.xml)" msgstr "Aqualung プレイリスト (*.xml)" msgid "MP3 Playlist (*.m3u)" msgstr "MP3 プレイリスト (*.m3u)" msgid "Multimedia Playlist (*.pls)" msgstr "マルチメディアプレイリスト (*.pls)" msgid "All Playlist Files" msgstr "全てのプレイリストファイル" msgid "All Audio Files" msgstr "全てのオーディオファイル" msgid "Sound Files (*.wav, *.aiff, *.au, ...)" msgstr "音声ファイル (*.wav, *.aiff, *.au, ...)" msgid "Free Lossless Audio Codec (*.flac)" msgstr "FLAC 可逆圧縮 (*.flac)" msgid "MPEG Audio (*.mp3, *.mpa, *.mpega, ...)" msgstr "MPEG オーディオ 非可逆圧縮 (*.mp3, *.mpa, *.mpega, ...)" msgid "Ogg Vorbis (*.ogg)" msgstr "Ogg Vorbis 非可逆圧縮 (*.ogg)" msgid "Ogg Speex (*.spx)" msgstr "Ogg Speex 非可逆圧縮 (*.spx)" msgid "Musepack (*.mpc)" msgstr "Musepack VBR 非可逆圧縮 (*.mpc)" msgid "Monkey's Audio Codec (*.ape)" msgstr "Monkey's Audio Codec 可逆圧縮 (*.ape)" msgid "Modules (*.xm, *.mod, *.it, *.s3m, ...)" msgstr "モジュール (*.xm, *.mod, *.it, *.s3m, ...)" msgid "Compressed modules (*.gz, *.bz2)" msgstr "圧縮モジュール (*.gz, *.bz2)" msgid "Compressed modules (*.gz)" msgstr "圧縮モジュール (*.gz)" msgid "Compressed modules (*.bz2)" msgstr "圧縮モジュール (*.bz2)" msgid "WavPack (*.wv)" msgstr "WavPack (*.wv)" msgid "LAVC audio/video files" msgstr "LAVC オーディオ/ビデオファイル" msgid "Resume" msgstr "レジューム" msgid "Calculating volume level" msgstr "音量レベルの計算中" msgid "Profile: Telephone" msgstr "プロファイル: 電話 (Telephone)" msgid "Profile: Thumb" msgstr "プロファイル: Thumb" msgid "Profile: Radio" msgstr "プロファイル: ラジオ (Radio)" msgid "Profile: Standard" msgstr "プロファイル: 標準 (Standard)" msgid "Profile: Xtreme" msgstr "プロファイル: 高音質 (Xtreme)" msgid "Profile: Insane" msgstr "プロファイル: 正気でない (Insane)" msgid "Profile: Braindead" msgstr "プロファイル: 脳死 (Braindead)" msgid "Layer I" msgstr "レイヤー I" msgid "Layer II" msgstr "レイヤー II" msgid "Layer III" msgstr "レイヤー III" msgid "Unrecognized" msgstr "認識されません" msgid "Single channel" msgstr "シングルチャンネル" msgid "Dual channel" msgstr "デュアルチャンネル" msgid "Joint stereo" msgstr "ジョイントステレオ" msgid "Stereo" msgstr "ステレオ" msgid "Emphasis: none" msgstr "Emphasis: なし" msgid "Emphasis:" msgstr "Emphasis:" msgid "Emphasis: reserved" msgstr "Emphasis: 予約" msgid "bit signed" msgstr "bit signed" msgid "bit unsigned" msgstr "bit unsigned" msgid "bit float" msgstr "bit float" msgid "bit double" msgstr "bit double" msgid "encoding" msgstr "エンコード" msgid "Compression: Fast" msgstr "圧縮: 高速 (Fast)" msgid "Compression: Normal" msgstr "圧縮: 標準 (Normal)" msgid "Compression: High" msgstr "圧縮: 高音質 (High)" msgid "Compression: Extra High" msgstr "圧縮: 超高音質 (Extra High)" msgid "Compression: Insane" msgstr "圧縮: 正気でない (Insane)" aqualung-0.9beta11/src/po/ru.po0000644000175000001440000027305511331334210013310 00000000000000# Russian translation for aqualung package. # Copyright (C) 2008 Tom Szilagyi # This file is distributed under the same license as the aqualung package. # Alexander Ilyashov , 2008. # msgid "" msgstr "" "Project-Id-Version: aqualung 0.9beta10\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2010-01-17 16:11+0200\n" "PO-Revision-Date: 2010-01-17 16:13+0300\n" "Last-Translator: Vladimir Smolyar \n" "Language-Team: Russian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Poedit-Language: Russian\n" msgid "About" msgstr "О программе" msgid "Build version: " msgstr "Версия сборки: " msgid "Homepage:" msgstr "Домашняя страница:" msgid "Authors:" msgstr "Авторы:" msgid "Core design, engineering & programming:\n" msgstr "Дизайн, проектирование и программирование:\n" msgid "Skin support, look & feel, GUI hacks:\n" msgstr "Поддержка скинов, внешний вид:\n" msgid "Programming, GUI engineering:\n" msgstr "Программирование, графический интерфейс:\n" msgid "OpenBSD compatibility, metadata tweaks:\n" msgstr "Совместимость с OpenBSD, трюки с метаданными:\n" msgid "Translators:" msgstr "Переводчики:" msgid "French:\n" msgstr "Французский:\n" msgid "German:\n" msgstr "Немецкий:\n" msgid "Hungarian:\n" msgstr "Венгерский:\n" msgid "Italian:\n" msgstr "Итальянский:\n" msgid "Japanese:\n" msgstr "Японский:\n" msgid "Russian:\n" msgstr "Русский:\n" msgid "Swedish:\n" msgstr "Шведский:\n" msgid "Ukrainian:\n" msgstr "Украинский:\n" msgid "Graphics:" msgstr "Графика:" msgid "Logo, icons:\n" msgstr "Логотип, иконки:\n" msgid "This Aqualung binary is compiled with:" msgstr "Этот исполнимый файл Aqualung скомпилирован с:" msgid "Optional features:" msgstr "Дополнительные возможности:" msgid "LADSPA plugin support\n" msgstr "Поддержка расширений LADSPA\n" msgid "CDDA (Audio CD) support\n" msgstr "Поддержка CDDA (Audio CD)\n" msgid "CDDB support\n" msgstr "Поддержка CDDB\n" msgid "Sample Rate Converter support\n" msgstr "Поддержка конвертера частоты дискретизации\n" msgid "iRiver iFP driver support\n" msgstr "Поддержка драйвера iRiver iFP\n" msgid "Loop playback support\n" msgstr "Поддержка зацикленного воспроизведения\n" msgid "Systray support\n" msgstr "Поддержка системного лотка\n" msgid "Podcast support\n" msgstr "Поддержка подкастов\n" msgid "Lua (programmable title formatting) support\n" msgstr "Поддержка Lua (программируемое форматирование заголовка)\n" msgid "Decoding support:" msgstr "Поддержка декодирования:" msgid "sndfile (WAV, AIFF, etc.)\n" msgstr "sndfile (WAV, AIFF, etc.)\n" msgid "Free Lossless Audio Codec (FLAC)\n" msgstr "Free Lossless Audio Codec (FLAC)\n" msgid "Ogg Vorbis\n" msgstr "Ogg Vorbis\n" msgid "Ogg Speex\n" msgstr "Ogg Speex\n" msgid "MPEG Audio (MPEG 1-2.5 Layer I-III)\n" msgstr "MPEG Audio (MPEG 1-2.5 Layer I-III)\n" msgid "MOD Audio (MOD, S3M, XM, IT, etc.)\n" msgstr "MOD Audio (MOD, S3M, XM, IT, etc.)\n" msgid "Musepack\n" msgstr "Musepack\n" msgid "Monkey's Audio Codec\n" msgstr "Monkey's Audio Codec\n" msgid "WavPack\n" msgstr "WavPack\n" msgid "LAVC (AC3, AAC, WavPack, WMA, etc.)\n" msgstr "LAVC (AC3, AAC, WavPack, WMA, etc.)\n" msgid "Encoding support:" msgstr "Поддержка кодирования:" msgid "sndfile (WAV)\n" msgstr "sndfile (WAV)\n" msgid "LAME (MP3)\n" msgstr "LAME (MP3)\n" msgid "Output driver support:" msgstr "Поддержка драйверов вывода:" msgid "sndio Audio\n" msgstr "sndio Audio\n" msgid "OSS Audio\n" msgstr "OSS Audio\n" msgid "ALSA Audio\n" msgstr "ALSA Audio\n" msgid "JACK Audio Server\n" msgstr "JACK Audio Server\n" msgid "PulseAudio\n" msgstr "PulseAudio\n" msgid "Win32 Sound API\n" msgstr "Win32 Sound API\n" msgid "" "This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.\n" "\n" "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.\n" "\n" "You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." msgstr "" "Эта программа является свободным программным обеспечением; вы можете распространять её и/или изменять по условиям Универсальной общественной лицензии GNU в виде, опубликованном Фондом свободного программного обеспечения; как версии 2, так и (по вашему усмотрению) любой более поздней версии.\n" "\n" "Эта программа распространяется в надежде, что она будет полезной, но БЕЗ КАКОЙ-ЛИБО ГАРАНТИИ; даже без подразумеваемой гарантии ТОВАРНОЙ ПРИГОДНОСТИ или СООТВЕТСТВИЯ КОНКРЕТНОМУ НАЗНАЧЕНИЮ. Для более детальной информации см. Универсальную общественную лицензию GNU.\n" "\n" "Вы должны были получить копию Универсальной общественной лицензии GNU вместе с этой программой; если нет, то напишите В Фонд свободного программного обеспечения: Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." msgid "Enabled" msgstr "Разрешён" msgid "Source" msgstr "Источник" msgid "CDDB" msgstr "CDDB" msgid "CDDB (not available)" msgstr "CDDB (недоступно)" msgid "Metadata" msgstr "Метаданные" msgid "Filesystem" msgstr "Файловая система" msgid "Capitalization" msgstr "Преобразование в заглавные буквы" msgid "Capitalize: " msgstr "Преобразовать в заглавные:" msgid "All words" msgstr "Все слова" msgid "First word only" msgstr "Только первое слово" msgid "Force case: " msgstr "Принудительно:" msgid "Force other letters to lowercase" msgstr "Преобразовать остальные буквы в нижний регистр" msgid "Regular expression" msgstr "Регулярное выражение" msgid "Regexp:" msgstr "РегВыр:" msgid "Replace:" msgstr "Замена:" msgid "Predefined transformations" msgstr "Предустановленные преобразования" msgid "Remove file extension" msgstr "Убирать расширение файла" msgid "Remove leading number" msgstr "Убирать число в начале" msgid "Convert underscore to space" msgstr "Преобразовывать подчеркивание в пробел" msgid "Trim leading, tailing and duplicate spaces" msgstr "Обрезать пробелы в начале, конце и повторяющиеся" msgid "Regexp matches empty string" msgstr "Регулярное выражение совпадает с пустой строкой" msgid "Please select the root directory." msgstr "Выберите, пожалуйста, корневой каталог." msgid "Select build type" msgstr "Выберите тип сборки" msgid "Directory driven" msgstr "В соответствии с каталогами" msgid "" "Follows the directory structure to identify the artists and\n" "records. The files are added on a record basis." msgstr "" "Следует по структуре каталогов для определения исполнителей и\n" "записей. Файлы добавляются на основе записей. " msgid "Independent" msgstr "Независимый" msgid "" "Recursive search from the root directory for audio files.\n" "The files are processed independently, so only metadata\n" "and filename transformation are available." msgstr "" "Рекурсивный поиск аудио файлов, начиная с корневого каталога.\n" "Файлы обрабатываются независимо, так что доступны только\n" "метаданные и преобразование имён файлов." msgid "Load settings from Music Store file" msgstr "Загрузить настройки из файла Музыкальной библиотеки" msgid "Build/Update store" msgstr "Построить/Обновить библиотеку" msgid "General" msgstr "Общие" msgid "Directory structure" msgstr "Структура каталога" msgid "Root path:" msgstr "Корневой путь:" msgid "_Browse..." msgstr "_Обзор..." msgid "Structure:" msgstr "Структура:" msgid "root / record / track" msgstr "корень / запись / трек" msgid "root / artist / record / track" msgstr "корень / исполнитель / запись / трек" msgid "root / artist / artist / record / track" msgstr "корень / исполнитель / исполнитель / запись / трек" msgid "root / artist / artist / artist / record / track" msgstr "корень / исполнитель / исполнитель / исполнитель / запись / трек" msgid "Exclude files matching wildcard" msgstr "Исключить файлы, удовлетворяющие маске" msgid "Include only files matching wildcard" msgstr "Включить только файлы, удовлетворяющие маске" msgid "Reread data for existing tracks" msgstr "Перечитать данные для имеющихся треков" msgid "Remove non-existing files from store" msgstr "Удалить несуществующие файлы из библиотеки" msgid "Artist" msgstr "Исполнитель" msgid "Sort artists by" msgstr "Сортировать исполнителей по" msgid "Artist name" msgstr "Имени исполнителя" msgid "Artist name (lowercase)" msgstr "Имени исполнителя (нижний регистр)" msgid "Directory name" msgstr "Имени каталога" msgid "Directory name (lowercase)" msgstr "Имени каталога (в нижнем регистре)" msgid "Record" msgstr "Запись" msgid "Sort records by" msgstr "Сортировать записи по" msgid "Record name" msgstr "Название записи" msgid "Record name (lowercase)" msgstr "Название записи (нижний регистр)" msgid "Year" msgstr "Год" msgid "Add year to the comments of new records" msgstr "Добавлять год в комментарии новых записей" msgid "Track" msgstr "Трек" msgid "Import Replaygain tag as manual RVA" msgstr "Импортировать тэг Replaygain как ручную настройку RVA" msgid "Import Comment tag" msgstr "Импортировать тэг комментария" msgid "Sandbox" msgstr "Песочница" msgid "Filename:" msgstr "Имя файла:" msgid "Test" msgstr "Тест" msgid "Building store from filesystem" msgstr "Построение библиотеки из файловой системы" msgid "Processing:" msgstr "Прогресс:" msgid "Action:" msgstr "Действие:" msgid "Abort" msgstr "Прервать" msgid "Unknown Artist" msgstr "Неизвестный исполнитель" msgid "Unknown Record" msgstr "Неизвестная запись" msgid "Scanning files" msgstr "Сканирование файлов" msgid "Processing metadata" msgstr "Обработка метаданных" msgid "CDDB lookup" msgstr "Поиск в CDDB" msgid "Name transformation" msgstr "Преобразование имени" msgid "Reading file" msgstr "Чтение файла" msgid "Removing non-existing files" msgstr "Удаление несуществующих файлов" msgid "Unknown disc" msgstr "Неизвестный диск" msgid "No disc" msgstr "Нет диска" msgid "CDDB query" msgstr "Запрос CDDB" msgid "Retrieving matches from server..." msgstr "Получение результатов с сервера..." msgid "Connecting to CDDB server..." msgstr "Подключение к серверу CDDB..." msgid "Error" msgstr "Ошибка" msgid "An error occurred while attempting to connect to the CDDB server." msgstr "Во время подключения к серверу CDDB возникла ошибка." msgid "Warning" msgstr "Внимание" msgid "No matching record found." msgstr "Совпадений не найдено." msgid "Import as Sort Key" msgstr "Импортировать как ключ сортировки" msgid "Import as Title" msgstr "Импортировать как заголовок" msgid "Import as Year" msgstr "Импортировать как год" msgid "" "Artist appears to be in all lowercase.\n" "Do you want to proceed?" msgstr "" "Имя исполнителя в нижнем регистре.\n" "Хотите продолжить?" msgid "" "Artist appears to be in all uppercase.\n" "Do you want to proceed?" msgstr "" "Имя исполнителя в верхнем регистре.\n" "Хотите продолжить?" msgid "" "Title appears to be in all lowercase.\n" "Do you want to proceed?" msgstr "" "Название в нижнем регистре.\n" "Хотите продолжить?" msgid "" "Title appears to be in all uppercase.\n" "Do you want to proceed?" msgstr "" "Название в верхнем регистре.\n" "Хотите продолжить?" msgid "" "It is very likely that the year is wrong.\n" "Do you want to proceed?" msgstr "" "Судя по всему, год указан неверно.\n" "Хотите продолжить?" msgid "The email address provided for submission is invalid." msgstr "Адрес электронной почты, предоставленный для подписки, недействителен." msgid "An error occurred while submitting the record to the CDDB server." msgstr "Во время отправки записи на сервер CDDB возникла ошибка." msgid "Correct existing record" msgstr "Исправить существующую запись" msgid "Submit new record" msgstr "Отправить новую запись" msgid "Matches:" msgstr "Совпадения:" msgid "Artist:" msgstr "Исполнитель:" msgid "Title:" msgstr "Название:" msgid "Year:" msgstr "Год:" msgid "Category:" msgstr "Категория." msgid "(choose a category)" msgstr "(выберите категорию)" msgid "Genre:" msgstr "Жанр:" msgid "Extended data:" msgstr "Расширенные данные:" msgid "Import as Artist" msgstr "Импортировать как исполнителя" msgid "Add to Comments" msgstr "Добавить в комментарии" msgid "Tracks" msgstr "Треки" msgid "You have to provide an email address for CDDB submission." msgstr "Вы должны указать адрес email для отправки CDDB." msgid "Please select the directory for ripped files." msgstr "Выберите, пожалуйста, каталог для извлеченных файлов." msgid "(none)" msgstr "(нет)" msgid "fast" msgstr "быстрее" msgid "best" msgstr "лучше" msgid "Compression level:" msgstr "Уровень сжатия:" msgid "Bitrate [kbps]:" msgstr "Битрейт [kbps]:" msgid "Artist/Album already existing, not empty" msgstr "Исполнитель/Альбом уже существуют и непусты" msgid "" "\n" "The Music Store you selected has a matching Artist and Album, already containing some tracks. If you press OK, these tracks will be removed. The files themselves will be left intact, but they will be removed from the destination Music Store. Press Cancel to get back to change the Artist/Album or the destination Music Store." msgstr "" "\n" "В выбранной вами Музыкальной библиотеке уже имеется исполнитель и альбом, содержащий треки. Если вы нажмете ОК, эти треки будут удалены. Файлы сами по себе тронуты не будут, но они будут удалены из данной Музыкальной библиотеки. Нажмите Отмена для возврата к изменению исполнителя/альбома или выбору другой Музыкальной библиотеки." msgid "Rip CD" msgstr "Извлечь музыку из CD" msgid "Album:" msgstr "Альбом:" msgid "Rip" msgstr "Извлечь музыку" msgid "No." msgstr "№" msgid "Title" msgstr "Заголовок" msgid "Select" msgstr "Выбрать" msgid "All" msgstr "Все" msgid "None" msgstr "Нет" msgid "Output" msgstr "Выход" msgid "Destination" msgstr "Цель" msgid "Target directory for ripped files" msgstr "Каталог назначения для извлеченных файлов" msgid "Add to Music Store" msgstr "Добавить в Музыкальную Библиотеку" msgid "Format" msgstr "Формат" msgid "File format:" msgstr "Формат файла:" msgid "VBR encoding" msgstr "Кодирование с переменным потоком" msgid "Tag files with metadata" msgstr "Ввести метаданные в файлы" msgid "Paranoia" msgstr "Paranoia" msgid "Paranoia error correction" msgstr "Корректирование ошибок Paranoia" msgid "Perform overlapped reads" msgstr "Производить чтения с перекрытием" msgid "Verify data integrity" msgstr "Проверить целостность данных" msgid "Unlimited retry on failed reads (never skip)" msgstr "Неограниченное число попыток при ошибках чтения (никогда не пропускать)" msgid "Maximum number of retries:" msgstr "Максимальное количество попыток:" msgid "" "\n" "Destination directory is not read-write accessible!" msgstr "" "\n" "Указанный каталог не доступен для чтения/записи!" msgid "Total" msgstr "Всего" msgid "(audio only)" msgstr "(только аудио)" msgid "Ripping CD tracks" msgstr "Считывание CD-треков" msgid "Begin" msgstr "Начало" msgid "Length" msgstr "Длина" msgid "Progress" msgstr "Прогресс" msgid "Close window when complete" msgstr "Закрыть окно после завершения" msgid "Close" msgstr "Закрыть" msgid "Unknown Album" msgstr "Неизвестный альбом" msgid "Unknown Track" msgstr "Неизвестный трек" msgid "Please select the directory for exported files." msgstr "Выберите, пожалуйста, каталог для экспортированных файлов." msgid "Copy" msgstr "Копировать" msgid "Help" msgstr "Помощь" #, c-format msgid "" "\n" "The template string you enter here will be used to construct the filename of the exported files. The Artist, Record and Track names are denoted by %%%%a, %%%%r and %%%%t. The track number and format-dependent file extension are denoted by %%%%n and %%%%x, respectively. The flag %%%%i gives an identifier which is unique within an export session." msgstr "" "\n" "Строка-шаблон, которую вы введёте сюда, будет использована для формирования имён экспортируемых файлов. Имена Исполнителя, Записи и Трека обозначаются %%%%a, %%%%r и %%%%t. Номер трека и расширение файла, зависящее от формата, обозначаются %%%%n и %%%%x, соответственно. Флаг %%%%i даёт идентификатор, уникальный для данной сеанса экспорта." msgid "Export files" msgstr "Экспорт файлов" msgid "Location and filename" msgstr "Местоположение и имя файла" msgid "Target directory:" msgstr "Каталог назначения:" msgid "Create subdirectories for artists" msgstr "Создать подкаталоги для исполнителей" msgid "Create subdirectories for albums" msgstr "Создать подкаталоги для альбомов" msgid "" "Subdirectory name\n" "length limit:" msgstr "" "Максимальная длина\n" "имени подкаталога:" msgid "Filename template:" msgstr "Шаблон имени файла:" msgid "Filter" msgstr "Фильтр" msgid "Do not reencode files already being in the target format" msgstr "Не перекодировать файлы, которые уже в нужном формате" msgid "" "Do not reencode files\n" "matching wildcard:" msgstr "" "Не перекодировать файлы,\n" "удовлетворяющие маске:" msgid "Error in format string" msgstr "Ошибка в строке формата" msgid "Exporting files" msgstr "Экспорт файлов" msgid "Source file:" msgstr "Исходный файл:" msgid "Target file:" msgstr "Файл назначения:" msgid "Progress:" msgstr "Прогресс:" msgid "*File info" msgstr "*Информация о файле" msgid "File info" msgstr "Информация о файле" msgid "There are unsaved changes to the file metadata." msgstr "Есть несохранённые изменения в метаданных файла." msgid "Save and close" msgstr "Сохранить и закрыть" msgid "Discard changes" msgstr "Отменить изменения" msgid "Do not close" msgstr "Не закрывать" #, c-format msgid "" "Conversion error in field %s:\n" "'%s' does not conform to format '%s'!" msgstr "" "Ошибка преобразования в поле %s:\n" "'%s' не соответсвует формату '%s'!" msgid "" "Attached Picture frame with no image set!\n" "Please set an image or remove the frame." msgstr "" "Вставлена картинка без изображения!\n" "Пожалуйста, установите изображение или удалите картинку." #, c-format msgid "" "Failed to write metadata to file.\n" "Reason: %s" msgstr "" "Невозможно записать метаданные в файл.\n" "Причина: %s" #, c-format msgid "" "Error converting field %s to Year:\n" "'%s' is not an integer number!" msgstr "" "Ошибка преобразования поля %s в год:\n" "'%s' не является целым числом!" msgid "Please specify the file to save the image to." msgstr "Укажите, пожалуйста, файл для сохранения изображения." msgid "(no image)" msgstr "(нет изображения)" msgid "(error loading image)" msgstr "(ошибка загрузки изображения)" msgid "Please specify the file to load the image from." msgstr "Укажите, пожалуйста, файл, из которого необходимо загрузить изображение." #, c-format msgid "" "Could not load image from:\n" "%s" msgstr "" "Невозможно загрузить изображение из:\n" "%s" #, c-format msgid "MIME type: %s" msgstr "Тип MIME: %s" msgid "Picture type:" msgstr "Тип изображения:" msgid "Description:" msgstr "Описание:" msgid "(no description)" msgstr "(нет описания)" msgid "Change" msgstr "Изменить" msgid "Save" msgstr "Сохранить" msgid "Import as Record" msgstr "Импортировать как запись" msgid "Import as Track No." msgstr "Импортировать как № трека" msgid "Import as RVA" msgstr "Импортировать как уровень RVA" msgid "Add" msgstr "Добавить" msgid "field:" msgstr "поле:" msgid "tag:" msgstr "тег:" msgid "Audio CD" msgstr "Аудио CD" msgid "Track:" msgstr "Трек:" msgid "File:" msgstr "Файл:" msgid "Audio data" msgstr "Аудиоданные" msgid "Format:" msgstr "Формат:" msgid "Length:" msgstr "Длина:" msgid "Samplerate:" msgstr "Частота дискретизации:" #, c-format msgid "%ld Hz" msgstr "%ld Гц" msgid "Channel count:" msgstr "Число каналов:" msgid "MONO" msgstr "МОНО" msgid "STEREO" msgstr "СТЕРЕО" msgid "Bandwidth:" msgstr "Поток:" msgid "Total samples:" msgstr "Всего сэмплов:" msgid "Mode:" msgstr "Режим:" msgid "Type:" msgstr "Тип:" msgid "Channels:" msgstr "Каналы:" msgid "Patterns:" msgstr "Паттернов:" msgid "Samples:" msgstr "Фрагментов:" msgid "Instruments:" msgstr "Инструменты:" msgid "Samples" msgstr "Фрагменты" msgid "Instruments" msgstr "Инструменты" msgid "Name" msgstr "Имя" msgid "STOPPING" msgstr "ОСТАНОВКА" msgid "Output:" msgstr "Вывод:" msgid "No output" msgstr "Нет вывода" msgid "SRC Type: " msgstr "Тип SRC:" #, c-format msgid "Loop range: %d-%d%% [%s - %s]" msgstr "Диапазон повтора: %d-%d%% [%s - %s]" #, c-format msgid "Loop range: %d-%d%%" msgstr "Диапазон повтора: %d-%d%%" msgid "" "One or more stores in Music Store have been modified.\n" "Do you want to save them before exiting?" msgstr "" "Одна или более библиотек в Музыкальной Библиотеке изменена.\n" "Хотите сохранить их перед выходом?" msgid "Do not exit" msgstr "Не выходить" msgid "Quit" msgstr "Выход" #, c-format msgid "Position: %d%%" msgstr "Позиция: %d%%" #, c-format msgid "Mute" msgstr "Приглушить звук" #, c-format msgid "%d dB" msgstr "%d дБ" #, c-format msgid "Volume: %s" msgstr "Громкость: %s" #, c-format msgid "%d%% R" msgstr "%d%% П" #, c-format msgid "%d%% L" msgstr "%d%% Л" #, c-format msgid "C" msgstr "Ц" #, c-format msgid "Balance: %s" msgstr "Баланс: %s" msgid "JACK connection lost" msgstr "Потеряно соединение JACK" msgid "JACK has either been shutdown or it disconnected Aqualung because it was not fast enough. All you can do now is restart both JACK and Aqualung." msgstr "JACK или выключился, или отсоединил Aqualung из-за того, что он был недостаточно быстр. Всё, что вы можете сейчас сделать, это перезапустить и JACK, и Aqualung" msgid "Warn me if the Window Manager does not support system tray" msgstr "Предупредить меня, если оконный менеджер не поддерживает системный лоток" msgid "Aqualung is compiled with system tray support, but the status icon could not be embedded in the notification area. Your desktop may not have support for a system tray, or it has not been configured correctly." msgstr "Aqualung скомпилирован с поддержкой системного лотка, но статусная иконка не может быть встроена в область уведомлений. Возможно, ваш рабочий стол не поддерживает системный лоток или неправильно настроен." msgid "Settings" msgstr "Настройки" msgid "Skin chooser" msgstr "Выбор скина" msgid "JACK port setup" msgstr "Настройка порта JACK" msgid "Previous song" msgstr "Предыдущая песня" msgid "Stop" msgstr "Стоп" msgid "Next song" msgstr "Следующая песня" msgid "Play/Pause" msgstr "Воспроизведение/Пауза" msgid "Play" msgstr "Играть" msgid "Pause" msgstr "Пауза" msgid "Repeat current song" msgstr "Повторять текущую песню" msgid "Repeat all songs" msgstr "Повторять все песни" msgid "Shuffle songs" msgstr "Перемешать песни" msgid "Toggle playlist" msgstr "Вкл./Выкл. плейлист" msgid "Toggle music store" msgstr "Вкл./Выкл. Музыкальную Библиотеку" msgid "Toggle LADSPA patch builder" msgstr "Вкл./Выкл. сборку патчей LADSPA" msgid "Show Aqualung" msgstr "Показать Aqualung" msgid "Hide Aqualung" msgstr "Скрыть Aqualung" msgid "Previous" msgstr "Предыдущий" msgid "Next" msgstr "Следующий" #, c-format msgid "%.1f MB / %.1f MB" msgstr "%.1f МБ / %.1f МБ" #, c-format msgid "%d / %d files" msgstr "%d / %d файлы" #, c-format msgid "%d / %d directories" msgstr "%d / %d каталогов" msgid "Cannot write to selected directory. Please select another directory." msgstr "Невозможно записать в выбранный каталог. Выберите, пожалуйста, другой каталог." msgid "Done" msgstr "Готово" msgid "Aborted..." msgstr "Отменено..." msgid "Please enter directory name." msgstr "Введите, пожалуйста, название каталога." msgid "Create directory" msgstr "Создать каталог" msgid "Please enter a new name." msgstr "Введите, пожалуйста, новое имя." msgid "Rename" msgstr "Переименовать" #, c-format msgid "" "Directory '%s' will be removed with its entire contents.\n" "\n" "Do you want to proceed?" msgstr "" "Каталог '%s' будет удалён вместе со всем содержимым.\n" "\n" "Хотите продолжить?" #, c-format msgid "" "File '%s' will be removed.\n" "\n" "Do you want to proceed?" msgstr "" "Файл '%s' будет удален.\n" "\n" "Хотите продолжить?" msgid "Remove" msgstr "Удалить" #, c-format msgid " (%.1f MB)" msgstr " (%.1f МБ)" #, c-format msgid " (capacity = %.1f MB)" msgstr " (ёмкость = %.1f МБ)" #, c-format msgid " Free space (%.1f MB)" msgstr " Свободное место (%.1f MБ)" msgid "" "No suitable iRiver iFP device found.\n" "Perhaps it is unplugged or turned off." msgstr "" "Подходящего устройства iRiver iFP не найдено.\n" "Возможно, оно отсоединено или выключено." msgid "" "Device is busy.\n" "(Aqualung was unable to claim its interface.)" msgstr "" "Устройство занято.\n" "(Aqualung не смог установить свой интерфейс.)" msgid "" "Device is not responding.\n" "Try jiggling the handle." msgstr "" "Устройство не отвечает.\n" "Попробуйте пошевелить рукояткой." msgid "Please select a local path." msgstr "Выберите, пожалуйста, локальный путь." msgid "Please select at least one valid song from playlist." msgstr "Выберите, пожалуйста, хотя бы одну допустимую песню из плей-листа." #, c-format msgid "" "One song has format unsupported by your player.\n" "\n" "Do you want to proceed?" msgstr "" "Одна из песен имеет формат, не поддерживаемый вашиим плеером.\n" "\n" "Хотите продолжить?" #, c-format msgid "" "%d of %d songs have format unsupported by your player.\n" "\n" "Do you want to proceed?" msgstr "" "%d из %d песен имеют формат, не поддерживаемый вашиим плеером.\n" "\n" "Хотите продолжить?" #, c-format msgid "" "The selected song has format unsupported by your player.\n" "\n" "Do you want to proceed?" msgstr "" "Выбранная песня имеет формат, не поддерживаемый вашиим плеером.\n" "\n" "Хотите продолжить?" #, c-format msgid "" "None of the selected songs has format supported by your player.\n" "\n" "Do you want to proceed?" msgstr "" "Формат ни одной из выбранных вами песен не поддерживается вашим плеером.\n" "\n" "Хотите продолжить?" msgid "iFP device manager (upload mode)" msgstr "Менеджер устройства iFP (режим выгрузки)" msgid "iFP device manager (download mode)" msgstr "Менеджер устройства iFP (режим загрузки)" msgid "Selected files:" msgstr "Выбранные файлы:" msgid "Songs info" msgstr "Информация о песнях" msgid "Model:" msgstr "Модель:" msgid "Battery" msgstr "Батарея" msgid "Free space" msgstr "Свободное место" msgid "Device status" msgstr "Состояние устройства" msgid "Size" msgstr "Размер" msgid "Create a new directory" msgstr "Создать новый каталог" msgid "Remote directory" msgstr "Удаленный каталог" msgid "Local directory" msgstr "Локальный каталог" msgid "Browse" msgstr "Обзор" msgid "File name: " msgstr "Имя файла:" msgid "Current file: " msgstr "Текущий файл:" msgid "Overall: " msgstr "Всего: " msgid "Idle" msgstr "Бездействие" msgid "Transfer progress" msgstr "Прогресс передачи" msgid "Close window when transfer complete" msgstr "Закрыть окно по окончании передачи" msgid "_Upload" msgstr "_Выгрузить" msgid "_Download" msgstr "_Загрузить" msgid "_Abort" msgstr "_Прервать" msgid "Success" msgstr "Успешно" msgid "Memory allocation error" msgstr "Ошибка выделения памяти" msgid "Unable to open file" msgstr "Невозможно открыть файл" msgid "No metadata support for this format" msgstr "Нет поддержки метаданных для этого формата" msgid "File is not writable" msgstr "Файл не доступен для записи" msgid "Invalid 'Track no.' field value" msgstr "Неверное значение поля 'Номер трека'" msgid "Invalid 'Genre' field value" msgstr "Неверное значение поля 'Жанр'" msgid "Conversion to target charset failed" msgstr "Преобразование в целевую кодировку не удалось" msgid "Internal error" msgstr "Внутренняя ошибка" msgid "Unknown error" msgstr "Неизвестная ошибка" msgid "Album" msgstr "Альбом" msgid "Date" msgstr "Дата" msgid "Genre" msgstr "Жанр" msgid "Track No." msgstr "Номер трека" msgid "Comment" msgstr "Комментарий" msgid "Disc" msgstr "Диск" msgid "Performer" msgstr "Исполнитель" msgid "Description" msgstr "Описание" msgid "Organization" msgstr "Организация" msgid "Location" msgstr "Расположение" msgid "Contact" msgstr "Контактная информация" msgid "License" msgstr "Лицензия" msgid "Copyright" msgstr "Авторское право" msgid "ISRC" msgstr "ISRC" msgid "Version" msgstr "Версия" msgid "Subtitle" msgstr "Подзаголовок" msgid "Debut Album" msgstr "Дебютный альбом" msgid "Publisher" msgstr "Издатель" msgid "Conductor" msgstr "Дирижёр" msgid "Composer" msgstr "Композитор" msgid "Publication Right" msgstr "Права на публикацию" msgid "File" msgstr "Файл" msgid "EAN/UPC" msgstr "EAN/UPC" msgid "ISBN" msgstr "ISBN" msgid "Catalog Number" msgstr "Номер каталога" msgid "Label Code" msgstr "Код лэйбла" msgid "Record Date" msgstr "Дата записи" msgid "Record Location" msgstr "Место записи" msgid "Media" msgstr "Носитель" msgid "Index" msgstr "Содержание" msgid "Related" msgstr "Связанное содержимое" msgid "Abstract" msgstr "Описание" msgid "Language" msgstr "Язык" msgid "Bibliography" msgstr "Библиография" msgid "Introplay" msgstr "Введение" msgid "BPM" msgstr "Ударов в секунду" msgid "Encoding Time" msgstr "Время кодирования" msgid "Playlist Delay" msgstr "Задержка плей-листа" msgid "Original Release Time" msgstr "Время выпуска оригинала" msgid "Release Time" msgstr "Дата релиза" msgid "Tagging Time" msgstr "Время внесения тэга" msgid "Encoded by" msgstr "Закодировано" msgid "Lyricist/Text Writer" msgstr "Поэт/автор текста" msgid "File Type" msgstr "Тип файла" msgid "Involved People" msgstr "Участники" msgid "Content Group" msgstr "Тип содержимого" msgid "Initial key" msgstr "Начальный ключ" msgid "Musician Credits" msgstr "Благодарности музыкантов" msgid "Mood" msgstr "Настроение" msgid "Original Album" msgstr "Оригинальное название альбома" msgid "Original Filename" msgstr "Оригинальное имя файла" msgid "Original Lyricist" msgstr "Оригинальное имя поэта" msgid "Original Artist" msgstr "Оригинальное имя исполнителя" msgid "File Owner" msgstr "Владелец файла" msgid "Band/Orchestra" msgstr "Группа/Оркестр" msgid "Interpreted/Remixed" msgstr "Интерпретация/Ремикс" msgid "Part Of A Set" msgstr "Часть набора" msgid "Produced" msgstr "Продюсер" msgid "Internet Radio Station Name" msgstr "Название интернет-радиостанции" msgid "Internet Radio Station Owner" msgstr "Владелец интернет-радиостанции" msgid "Album Sort Order" msgstr "Порядок сортировки альбомов" msgid "Performer Sort Order" msgstr "Порядок сортировки Исполнителей" msgid "Title Sort Order" msgstr "Порядок сортировки названий" msgid "Software" msgstr "Программа" msgid "Set Subtitle" msgstr "Установить подзаголовок" msgid "User Defined Text" msgstr "Пользовательский текст" msgid "Commercial Information" msgstr "Коммерческая информация" msgid "Copyright/Legal Information" msgstr "Авторское право/юридическая информация" msgid "Official Audio File Website" msgstr "Официальная веб-страница аудиофайла" msgid "Official Artist Website" msgstr "Официальная веб-страница исполнителя" msgid "Official Audio Source Website" msgstr "Официальная веб-страница источника аудио" msgid "Official Radio Station Website" msgstr "Официальная веб-страница радиостанции" msgid "Payment" msgstr "Оплата" msgid "Publisher's Official Website" msgstr "Официальная веб-страница издателя" msgid "User Defined URL" msgstr "Пользовательский URL" msgid "Vendor" msgstr "Производитель" msgid "ReplayGain Reference Loudness" msgstr "Опорная громкость Выравнивания громкости (ReplayGain)" msgid "ReplayGain Track Gain" msgstr "Коэффициент усиления трека для выравнивания громкости (ReplayGain)" msgid "ReplayGain Track Peak" msgstr "Пик трека для выравнивания громкости (ReplayGain)" msgid "ReplayGain Album Gain" msgstr "Коэффициент усиления альбома для выравнивания громкости (ReplayGain)" msgid "ReplayGain Album Peak" msgstr "Пик альбома для выравнивания громкости (ReplayGain)" msgid "Icy-Name" msgstr "Название станции" msgid "Icy-Description" msgstr "Описание станции" msgid "Icy-Genre" msgstr "Жанр станции" msgid "RVA" msgstr "АУГ (RVA)" msgid "Attached Picture" msgstr "Прикреплённая картинка" msgid "Binary Object" msgstr "Двоичный объект" msgid "NULL" msgstr "NULL" msgid "ID3v1" msgstr "ID3v1" msgid "ID3v2" msgstr "ID3v2" msgid "APE" msgstr "APE" msgid "Ogg Xiph Comments" msgstr "Комментарии Ogg Xiph" msgid "FLAC Pictures" msgstr "Картинки FLAC" msgid "Musepack ReplayGain" msgstr "Уравнивание громкости Musepack" msgid "Generic StreamMeta" msgstr "Общие метаданные потока" msgid "MPEG StreamMeta" msgstr "Метаданные MPEG-потока" msgid "Module info" msgstr "Информация о модуле" msgid "Unknown" msgstr "Неизвестный" msgid "Other" msgstr "Другое" msgid "File icon (32x32 PNG)" msgstr "Значок файла (32x32 PNG)" msgid "File icon (other)" msgstr "Значок файла (другое)" msgid "Front cover" msgstr "Передняя обложка" msgid "Back cover" msgstr "Задняя обложка" msgid "Leaflet page" msgstr "Вкладыш" msgid "Album image" msgstr "Изображение альбома" msgid "Lead artist/performer" msgstr "Ведущий певец/исполнитель" msgid "Artist/performer" msgstr "Певец/Исполнитель" msgid "Band/orchestra" msgstr "Группа/оркестр" msgid "Lyricist/text writer" msgstr "Поэт/автор текста" msgid "Recording location/studio" msgstr "Место записи/студия" msgid "During recording" msgstr "Во время записи" msgid "During performance" msgstr "Во время исполнения" msgid "Movie/video screen capture" msgstr "Кадр из кино/видеофильма" msgid "A large, coloured fish" msgstr "Большая цветная рыба" msgid "Illustration" msgstr "Иллюстрация" msgid "Band/artist logotype" msgstr "Логотип группы/исполнителя" msgid "Publisher/studio logotype" msgstr "Логотип издателя/студии" msgid "Music Store" msgstr "Музыкальная библиотека" msgid "Search..." msgstr "Поиск..." msgid "Collapse all items" msgstr "Свернуть все элементы" msgid "Edit item..." msgstr "Редактировать элемент..." msgid "Add item..." msgstr "Добавить элемент..." msgid "Remove item..." msgstr "Удалить элемент..." msgid "Save all stores" msgstr "Сохранить все библиотеки" msgid "Create empty store..." msgstr "Создать пустую библиотеку..." msgid "*Music Store" msgstr "*Музыкальная библиотека" #, c-format msgid "Do you want to save store \"%s\" before removing from Music Store?" msgstr "Хотите сохранить библиотеку \"%s\" перед удалением из Музыкальной Библиотеки?" msgid "You will need to restart Aqualung for the following changes to take effect:" msgstr "Вам придётся перезапустить Aqualung, чтобы вступили в силу следующие изменения:" msgid "Select a font..." msgstr "Выбрать шрифт..." msgid "Disable skin support" msgstr "Отключить поддержку скинов" msgid "rw" msgstr "чтение/запись" msgid "r" msgstr "только чтение" msgid "unreachable" msgstr "Недосягаем" msgid "Please select a Programable Title Format File." msgstr "Выберите, пожалуйста файл программируемого форматирования заголовка." msgid "Please select a Music Store database." msgstr "Выберите, пожалуйста, базу данных музыкальной библиотеки." msgid "Paths must either be absolute or starting with a tilde." msgstr "Пути должны быть абсолютными или начинаться с тильды." msgid "The specified store has already been added to the list." msgstr "Указанная библиотека уже добавлена в список." #, c-format msgid "" "\n" "The template string you enter here will be used to construct a single title line from an Artist, a Record and a Track name. These are denoted by %%%%a, %%%%r and %%%%t, respectively.\n" msgstr "" "\n" "Строка-шаблон, которую вы введёте здесь, будет использоваться для формирования строки заголовка из имён Исполнителя, Записи и Трека. Они обозначены %%%%a, %%%%r и %%%%t соответственно.\n" msgid "" "\n" "The file you enter/choose here will set the Lua program to use to format the title. See the Aqualung manual for details. Here is a quick example of what you can use in the file:\n" "\n" "function playlist_title()\n" " return m('artist') .. '-' .. m('title') .. ' (' .. m('album') .. ') (' .. i('filename') .. ')'\n" "end" msgstr "" "\n" "Файл, который вы введёте/выберете здесь, установит программу на Lua, используемуюдля форматирования заголовка. Для доп. информации см. справку по Aqualung. Вот быстрый пример того, что вы можете использовать в этом файле:\n" "\n" "function playlist_title()\n" " return m('artist') .. '-' .. m('title') .. ' (' .. m('album') .. ') (' .. i('filename') .. ')'\n" "end" msgid "" "\n" "The string you enter here will be parsed as a command line before parsing the actual command line parameters. What you enter here will act as a default setting and may or may not be overridden from the 'real' command line.\n" "\n" "Example: enter '-o alsa -R' below to use ALSA output running realtime as a default.\n" msgstr "" "\n" "Строка, которую вы введёте здесь, будет представлена, как командная строка перед обработкой действительных параметров командной строки. То, что вы введёте здесь, будет действовать как значение по умолчанию и может или не может быть отменено из 'настоящей' командной строки.\n" "\n" "Пример: введите '-o alsa -R' ниже для использования вывода через ALSA в реальном времени по умолчанию.\n" msgid "" "Paths must either be absolute or starting with a tilde, which will be expanded to the user's home directory.\n" "\n" "Drag and drop entries in the list to set the store order in the Music Store." msgstr "" "Пути должны быть или абсолютными, или начинаться с тильды, которая будет преобразована в домашний каталог пользователя.\n" "\n" "Перетащите содержимое в списке, чтобы установить порядок хранения в Музыкальной Библиотеке." msgid "" "\n" "Set the drive speed for CD playing in CD-ROM speed units. One speed unit equals to 176 kBps raw data reading speed. Warning: not all drives honor this setting.\n" "\n" "Lower speed usually means less drive noise. However, when using Paranoia error correction modes for increased accuracy, generally much larger speeds are required to prevent buffer underruns (and thus audible drop-outs).\n" "\n" "Please note that these settings do not apply to CD Ripping, which always happens with maximum available speed and with error correction modes manually set before every run." msgstr "" "\n" "Установите скорость привода для проигрывания CD в единицах скорости CD-ROM. Одна единица скорости соответсвует скорости чтения данных 176 кбит/с. Предупреждение: не все приводы принимают эту установку.\n" "\n" "Низшая скорость обычно означает меньше шума от привода. Однако, при использовании режимов коррекции ошибок Paranoia для повышенной точности, обычно необходимы намного большие скорости, чтобы предотвратить опустошение буфера (и как следствие - слышимых выпадений).\n" "\n" "Пожалуйста, обратите внимание на то, что эти настройки не влияют на извлечение музыки с CD (Ripping), которое всегда происходит на максимальной доступной скорости и с ручной установкой режимов коррекции ошибок перед каждым сеансом." msgid "" "\n" "Most drives let Aqualung know when a CD has been inserted or removed by providing a 'media changed' flag. However, some drives don't set this flag properly, and thus it may happen that a newly inserted CD remains unnoticed to Aqualung. In such cases, enabling this option should help." msgstr "" "\n" "Большинство приводов дают Aqualung'у знать, когда вставлен или извлечён CD, уснанавливая флаг 'носитель сменён'. Однако, некоторые приводы не устанавливают этот флаг должным образом, и поэтому вновь вставленный CD может остаться незамеченным Aqualung'ом. В таких случаях должно помочь включение данной функции." msgid "" "\n" "Here you should enter a comma-separated list of domains\n" "that should be accessed without using the proxy set above.\n" "Example: localhost, .localdomain, .my.domain.com" msgstr "" "\n" "Здесь вы должны ввести через запятую список доменов,\n" "доступ к которым должен осуществляться без использования\n" "прокси, установленного выше.\n" "Пример: localhost, .localdomain, .my.domain.com" msgid "Embed playlist into main window" msgstr "Встроить плейлист в основное окно" msgid "Enable systray" msgstr "Разрешить системный лоток" msgid "Do nothing" msgstr "Ничего не делать" msgid "Change volume" msgstr "Изменить громкость" msgid "Change balance" msgstr "Изменить баланс" msgid "Change song position" msgstr "Изменить позицию песни" msgid "Change current song" msgstr "Изменить текущую песню" msgid "Left button" msgstr "Левая кнопка" msgid "Middle button" msgstr "Средняя кнопка" msgid "Right button" msgstr "Правая кнопка" msgid "Button" msgstr "Кнопка" msgid "Left and right mouse buttons are reserved." msgstr "Левая и правая кнопки мыши зарезервированы." msgid "This button is already assigned." msgstr "Эта клавиша уже назначена." msgid "Add mouse button command" msgstr "Добавить команду для кнопки мыши" msgid "Mouse button" msgstr "Кнопка мыши" msgid "Click here to set mouse button" msgstr "Щёлкните здесь, чтобы установить кнопку мыши" msgid "Command" msgstr "Команда" msgid "Main window" msgstr "Главное окно" msgid "Disable control buttons relief" msgstr "Отключить рельеф управляющих кнопок" msgid "Combine play and pause buttons" msgstr "Объединить кнопки паузы и воспроизведения" msgid "Keep main window always on top" msgstr "Размещать главное окно всегда сверху" msgid "Show song name in the main window's title" msgstr "Показывать название песни в заголовке главного окна" msgid "Title Format" msgstr "Формат заголовка" msgid "Programmable title format file" msgstr "файл программируемого форматирования заголовка" msgid "Systray" msgstr "Системный лоток" msgid "Start minimized" msgstr "Запускать минимизированным" msgid "Play/Stop song" msgstr "Играть/Остановить песню" msgid "Play/Pause song" msgstr "Играть/Остановить песню" msgid "Mouse wheel" msgstr "Колесо мыши" msgid "Vertical mouse wheel:" msgstr "Вертикальное колесо мыши:" msgid "Horizontal mouse wheel:" msgstr "Горизонтальное колесо мыши:" msgid "Mouse buttons" msgstr "Кнопки мыши" msgid "Miscellaneous" msgstr "Разное" msgid "Implicit command line" msgstr "подразумеваемая командная строка" msgid "Cover art" msgstr "Обложка" msgid "Default cover width:" msgstr "Ширина обложки по умолчанию:" msgid "50 pixels" msgstr "50 пикселов" msgid "100 pixels" msgstr "100 пикселов" msgid "200 pixels" msgstr "200 пикселов" msgid "300 pixels" msgstr "300 пикселов" msgid "use browser window width" msgstr "использовать ширину окна браузера" msgid "Do not magnify images with smaller width" msgstr "Не увеличивать изображения меньшей ширины" msgid "Show cover thumbnail for Music Store tracks only" msgstr "Показывать миниатюру обложки только для треков из Музыкальной библиотеки" msgid "Don't show cover thumbnail in the main window" msgstr "Не показывать миниатюру обложки в главном окне" msgid "Enable tooltips" msgstr "Включить подсказки" msgid "Simple view in LADSPA patch builder" msgstr "Простой вид в сборщике патчей LADSPA" msgid "United windows minimization" msgstr "Объединённая минимизация окон" msgid "Show hidden files and directories in file choosers" msgstr "Показывать скрытые файлы и каталоги в диалогах выбора файла" msgid "Show tags tab first in the file info dialog" msgstr "Показывать вкладку тэгов первой в окне информации о файле" msgid "Playlist" msgstr "Плей-лист" msgid "Put control buttons at the bottom of playlist" msgstr "Разместить кнопки управления внизу плей-листа" msgid "Save and restore the playlist on exit/startup" msgstr "Сохранять и восстанавливать плей-лист при закрытии/запуске" msgid "Save playlist periodically [min]:" msgstr "Периодически сохранять плей-лист [мин.]:" msgid "Album mode is the default when adding entire records" msgstr "Режим альбома используется по умолчанию при добавлении целых записей" msgid "Always show the tab bar" msgstr "Всегда показывать строку вкладок" msgid "Show close button in tab" msgstr "Показывать кнопку закрытия в закладке" msgid "When shuffling, records added in Album mode are played in order" msgstr "В режиме перемешивания записи, добавленные в режиме альбома, проигрываются по порядку" msgid "Enable statusbar" msgstr "Включить строку состояния" msgid "Enable statusbar in playlist" msgstr "Включить строку состояния в плей-листе" msgid "Show soundfile size in statusbar" msgstr "Отображать размер файла в строке состояния" msgid "Show RVA values" msgstr "Показать значения RVA" msgid "Show track lengths" msgstr "Показывать длину треков" msgid "Show active track name in bold" msgstr "Показывать название активного трека жирным" msgid "Automatically roll to active track" msgstr "Автоматически перемещаться к активной песне" msgid "Enable rules hint" msgstr "Чередующаяся окраска строк в списке" msgid "Playlist column order" msgstr "Порядок колонок в плей-листе" msgid "" "Drag and drop entries in the list below \n" "to set the column order in the Playlist." msgstr "" "Перетащите содержимое в списке ниже, \n" "чтобы установить порядок колонок в плейлисте." msgid "Column" msgstr "Колонка" msgid "Track titles" msgstr "Названия треков" msgid "RVA values" msgstr "Значения RVA" msgid "Track lengths" msgstr "Длины треков" msgid "Hide comment pane" msgstr "Спрятать панель комментария" msgid "Hide the Music Store comment pane" msgstr "Спрятать панель комментария в Музыкальной Библиотеке" msgid "Enable toolbar" msgstr "Включить панель инструментов" msgid "Enable toolbar in Music Store" msgstr "Разрешить панель инструментов в Музыкальной библиотеке" msgid "Enable statusbar in Music Store" msgstr "Разрешить строку состояния в Музыкальной библиотеке" msgid "Expand Stores on startup" msgstr "Развернуть библиотеки при запуске" msgid "Enable tree node icons" msgstr "Разрешить значки узлов дерева" msgid "Enable Music Store tree node icons" msgstr "Разрешить значки узлов дерева в Музыкальной Библиотеке" msgid "Ask for confirmation when removing items" msgstr "Запрашивать подтверждение перед удалением элементов" msgid "Paths to Music Store databases" msgstr "Пути к базам данных музыкальной библиотеки" msgid "Path" msgstr "Путь" msgid "Access" msgstr "Доступ" msgid "Refresh" msgstr "Обновить" msgid "DSP" msgstr "DSP" msgid "LADSPA plugin processing" msgstr "Обработка дополнения LADSPA" msgid "Pre Fader (before Volume & Balance)" msgstr "Предусилитель (до громкости и баланса)" msgid "Post Fader (after Volume & Balance)" msgstr "Постусилитель (после громкости и баланса)" msgid "" "Aqualung is compiled without LADSPA plugin support.\n" "See the About box and the documentation for details." msgstr "" "Aqualung скомпилирован без поддержки дополнений LADSPA.\n" "Детали см. в окне О программе и документации." msgid "Sample Rate Converter type" msgstr "Тип преобразователя частоты дискретизации" msgid "" "Aqualung is compiled without Sample Rate Converter support.\n" "See the About box and the documentation for details." msgstr "" "Aqualung скомпилирован без поддержки Преобразователя частоты дискретизации.\n" "Детали см. в окне О программе и документации." msgid "Playback RVA" msgstr "АУГ (RVA)" msgid "Enable playback RVA" msgstr "Включить Автоматическое Уравнивание Громкости (RVA)" msgid "Listening environment:" msgstr "Среда прослушивания:" msgid "Audiophile" msgstr "Аудиофил" msgid "Living room" msgstr "Гостинная" msgid "Office" msgstr "Офис" msgid "Noisy workshop" msgstr "Шумная мастерская" msgid "Reference volume [dBFS] :" msgstr "Опорный уровень [дБ полная шкала] :" msgid "Steepness [dB/dB] :" msgstr "Крутизна [dB/dB] :" msgid "RVA for Unmeasured Files [dB] :" msgstr "Уровень RVA для неизмеренных файлов [дБ] :" msgid "Apply averaged RVA to tracks of the same record" msgstr "Применить усреднённый уровень RVA для треков из одной записи" msgid "Drop statistical aberrations based on" msgstr "Пренебрегать случайными отклонениями, основываясь на" #, no-c-format msgid "% of standard deviation" msgstr "% от стандартного отклонения" msgid "Linear threshold [dB]" msgstr "Линейном пороге [дБ]" msgid "Linear threshold [dB] :" msgstr "Линейный порог [дБ] :" #, no-c-format msgid "% of standard deviation :" msgstr "% от стандартного отклонения :" msgid "ReplayGain tag to use (with fallback to the other): " msgstr "Используемый тэг ReplayGain (с отходом на другой):" msgid "Replaygain_track_gain" msgstr "Replaygain_track_gain" msgid "Replaygain_album_gain" msgstr "Replaygain_track_gain" msgid "Adding files to Playlist" msgstr "Добавление файлов в плей-лист" msgid "" "Use basename only instead of full path\n" "if no metadata is available." msgstr "" "Использовать только основное имя вместо\n" "полного пути, если не доступны метаданные." msgid "Metadata editor (File info dialog)" msgstr "Редактор метаданных (диалог информации о файле)" msgid "" "When adding new frames, try to set their contents\n" "from another tag's equivalent frame." msgstr "" "При добавлении новых полей пытаться установить их содержимое\n" "из эквивалентных полей другого тэга." msgid "Batch update & encode (mass tagger, CD ripper, file export)" msgstr "Пакетное обновление и кодирование (массовое заполнение тэгов, извлечение из CD, экспорт файлов)" msgid "Tags to add when creating or updating MPEG audio files:" msgstr "Тэги, добавляемые при создании или изменении аудиофайлов MPEG:" msgid "" "Note: pre-existing tags will be updated even though they\n" "might not be checked here." msgstr "" "Примечание: существующие тэги будут обновлены даже если они\n" "не выбраны здесь." msgid "CD Audio" msgstr "CD Audio" msgid "CD drive speed:" msgstr "Скорость привода CD:" msgid "\tMaximum number of retries:" msgstr "\tМаксимальное количество попыток:" msgid "Force TOC re-read on every drive scan" msgstr "Принудительно перечитывать таблицу файлов при каждом сканировании диска" msgid "Automatically add CDs to Playlist" msgstr "Автоматически добавлять CD в плей-лист" msgid "Automatically remove CDs from Playlist" msgstr "Автоматически удалять CD из плейлиста" msgid "CDDB server:" msgstr "Сервер CDDB:" msgid "Connection timeout [sec]:" msgstr "Лимит времени ожидания соединения [сек]:" msgid "Email address for submission:" msgstr "Адрес электронной почты для подписки:" msgid "Local CDDB directory:" msgstr "Локальный каталог CDDB:" msgid "Use the local database only" msgstr "Использовать только локальную базу данных" msgid "Protocol for querying (direct connection only):" msgstr "Протокол для запросов (только прямое соединение):" msgid "CDDBP (port 888)" msgstr "CDDBP (порт 888)" msgid "HTTP (port 80)" msgstr "HTTP (порт 80)" msgid "Internet" msgstr "Интернет" msgid "Direct connection to the Internet" msgstr "Прямое подключение к Интернету" msgid "Connect via HTTP proxy" msgstr "Подключение через HTTP-прокси" msgid "Proxy settings" msgstr "Настройки прокси" msgid "Proxy host:" msgstr "Адрес прокси:" msgid "Port:" msgstr "Порт:" msgid "No proxy for:" msgstr "Не использовать прокси для:" msgid "Timeout for socket I/O:" msgstr "Время ожидания ввода/вывода сокета:" msgid "seconds" msgstr "секунд" msgid "Appearance" msgstr "Внешний вид" msgid "Override skin settings" msgstr "Сбросить настройки скина" msgid "Fonts" msgstr "Шрифты" msgid "Playlist: " msgstr "Плей-лист: " msgid "Music Store: " msgstr "Музыкальная библиотека: " msgid "Big timer: " msgstr "Большой таймер: " msgid "Small timers: " msgstr "Маленькие таймеры: " msgid "Song title: " msgstr "Название песни: " msgid "Song info: " msgstr "Информация о песне: " msgid "Statusbar: " msgstr "Строка состояния: " msgid "Colors" msgstr "Цвета" msgid "Song in playlist: " msgstr "Песня в плей-листе: " msgid "Active song in playlist: " msgstr "Активная песня в плей-листе: " msgid "Error in title format string" msgstr "Ошибка в строке формата заголовка" msgid "(Untitled)" msgstr "(без названия)" #, c-format msgid " (%d/%d)" msgstr " (%d/%d)" msgid "Select files" msgstr "Выбрать файлы" msgid "Select directory" msgstr "Выбрать каталог" msgid "Add URL" msgstr "Добавить URL" msgid "URL:" msgstr "URL:" msgid "Please specify the file to save the playlist to." msgstr "Укажите, пожалуйста, файл для сохранения плей-листа." msgid "Please specify the file to load the playlist from." msgstr "Укажите, пожалуйста, файл, из которого необходимо загрузить плей-лист." msgid "" "Playback RVA is currently disabled.\n" "Do you want to enable it now?" msgstr "" "АУГ (RVA) в данный момент отключено.\n" "Хотите включить его сейчас?" msgid "counting..." msgstr "подсчет..." msgid "track" msgstr "дорожка" msgid "tracks" msgstr "дорожки" msgid "Rename playlist" msgstr "Переименовать плей-лист" msgid "Name:" msgstr "Имя:" msgid "New tab" msgstr "Новая вкладка" msgid "Close tab" msgstr "Закрыть вкладку" msgid "Undo close tab" msgstr "Отменить закрытие вкладки" msgid "Close other tabs" msgstr "Закрыть другие вкладки" msgid " Selected: " msgstr "Выбранные: " msgid "Total: " msgstr "Всего:" msgid "Add files" msgstr "Добавить файлы" msgid "" "Add files to playlist\n" "(Press right mouse button for menu)" msgstr "" "Добавить файлы в плей-лист\n" "(Нажмите правой кнопкой мыши, чтобы открыть меню)" msgid "Select all" msgstr "Выбрать все" msgid "" "Select all songs in playlist\n" "(Press right mouse button for menu)" msgstr "" "Выбрать все песни плей-листа\n" "(Нажмите правой кнопкой мыши, чтобы открыть меню)" msgid "Remove selected" msgstr "Удалить выделенные" msgid "" "Remove selected songs from playlist\n" "(Press right mouse button for menu)" msgstr "" "Удалить выделенные песни из плей-листа\n" "(Нажмите правой кнопкой мыши, чтобы открыть меню)" msgid "Add directory" msgstr "Добавить каталог" msgid "Select none" msgstr "Ничего не выбирать" msgid "Invert selection" msgstr "Инвертировать выделение" msgid "Remove all" msgstr "Удалить все" msgid "Remove dead" msgstr "Удалить мёртвые" msgid "Cut selected" msgstr "Вырезать выбранное" msgid "Save playlist" msgstr "Сохранить плей-лист" msgid "Save all playlists" msgstr "Сохранить все плей-листы" msgid "Load playlist in new tab" msgstr "Загрузить плей-лист в новую вкладку" msgid "Load playlist" msgstr "Загрузить плей-лист" msgid "Enqueue playlist" msgstr "Добавить в плей-лист" msgid "Send to iFP device" msgstr "Отправить на устройство iFP" msgid "Calculate RVA" msgstr "Вычислить уровень RVA" msgid "Separate" msgstr "По отдельности" msgid "Average" msgstr "Средний" msgid "Reread file metadata" msgstr "Перечитать метаданные файла" msgid "File info..." msgstr "Информация о файле..." msgid "Roll to active song" msgstr "Скатиться к активной песне" msgid "Stop adding files" msgstr "Остановить добавление файлов" msgid "Files selected for removal" msgstr "Выбранные для удаления файлы" msgid "Remove files" msgstr "Удалить файлы" msgid "" "The selected files will be deleted from the filesystem. No recovery will be possible after this operation.\n" "\n" "Do you want to proceed?" msgstr "" "Выбранные файлы будут удалены из файловой системы. После этого восстановить их будет невозможно.\n" "\n" "Хотите продолжить?" #, c-format msgid "Unable to remove %d file." msgstr "Невозможно удалить %d файл." #, c-format msgid "Unable to remove %d files." msgstr "Невозможно удалить %d файлов" msgid "LADSPA patch builder" msgstr "Сборщик патчей LADSPA" msgid "Available plugins" msgstr "Доступные расширения" msgid "ID" msgstr "ID" msgid "Category" msgstr "Категория" msgid "Inputs" msgstr "Входы" msgid "Outputs" msgstr "Выходы" msgid "Running plugins" msgstr "Запущенные расширения" msgid "_Configure" msgstr "_Настройки" msgid "Enable all plugins" msgstr "Включить все расширения" msgid "Disable all plugins" msgstr "Отключить все расширения" msgid "Invert current state" msgstr "Инвертировать текущее состояние" msgid "Clear list" msgstr "Очистить список" msgid "Untitled" msgstr "Без названия" msgid "JACK Port Setup" msgstr "Настройка порта JACK" msgid "Rescan" msgstr "Перечитать" msgid "Available connections" msgstr "Доступные соединения" msgid "Clear connections" msgstr "Закрыть соединения" msgid " out L" msgstr "вых Л" msgid " out R" msgstr "вых П" msgid "Search the Music Store" msgstr "Поиск в музыкальной библиотеке" msgid "Key: " msgstr "Ключ: " msgid "Case sensitive" msgstr "С учётом регистра" msgid "Exact matches only" msgstr "Только точные совпадения" msgid "Select first and close window" msgstr "Выбрать первый и закрыть окно" msgid "Search in:" msgstr "Искать в:" msgid "Artist names" msgstr "Именах исполнителей" msgid "Record titles" msgstr "Названиях записей" msgid "Comments" msgstr "Комментариях" msgid "Search" msgstr "Поиск" msgid "Search the Playlist" msgstr "Поиск в плей-листе" msgid "Available skins" msgstr "Доступные скины" msgid "Drive info" msgstr "Информация о диске" msgid "Device path:" msgstr "Путь к устройству:" msgid "Vendor:" msgstr "Производитель:" msgid "Revision:" msgstr "Пересмотр:" msgid "" "The information below is reported by the drive, and\n" "may not reflect the actual capabilities of the device." msgstr "" "Информация ниже получена из устройства, и может не\n" "отображать действительных возможностей устройства." msgid "Eject" msgstr "Извлечение лотка" msgid "Close tray" msgstr "Закрытие лоток" msgid "Disable manual eject" msgstr "Запрет ручного извлечения" msgid "Select juke-box disc" msgstr "Выбор диска в CD-чейнджере" msgid "Set drive speed" msgstr "Выбор скорости привода" msgid "Detect media change" msgstr "Определение смены носителя" msgid "Read multiple sessions" msgstr "Чтение многосессионных дисков" msgid "Hard reset device" msgstr "Жёсткий сброс устройства" msgid "Reading" msgstr "Чтение" msgid "Play CD Audio" msgstr "Проигрывание CD Audio" msgid "Read CD-DA" msgstr "Чтение CD-DA" msgid "Read CD+G" msgstr "Чтение CD+G" msgid "Read CD-R" msgstr "Чтение CD-R" msgid "Read CD-RW" msgstr "Чтение CD-RW" msgid "Read DVD-R" msgstr "Чтение DVD-R" msgid "Read DVD+R" msgstr "Чтение DVD+R" msgid "Read DVD-RW" msgstr "Чтение DVD-RW" msgid "Read DVD+RW" msgstr "Чтение DVD+RW" msgid "Read DVD-RAM" msgstr "Чтение DVD-RAM" msgid "Read DVD-ROM" msgstr "Чтение DVD-ROM" msgid "C2 Error Correction" msgstr "Коррекция ошибок C2" msgid "Read Mode 2 Form 1" msgstr "Чтение Mode 2 Form 1" msgid "Read Mode 2 Form 2" msgstr "Чтение Mode 2 Form 2" msgid "Read MCN" msgstr "Считывать MCN" msgid "Read ISRC" msgstr "Считывание ISRC (Международного стандартного номера записи)" msgid "Writing" msgstr "Запись" msgid "Write CD-R" msgstr "Запись CD-R" msgid "Write CD-RW" msgstr "Запись CD-RW" msgid "Write DVD-R" msgstr "Запись DVD-R" msgid "Write DVD+R" msgstr "Запись DVD+R" msgid "Write DVD-RW" msgstr "Запись DVD-RW" msgid "Write DVD+RW" msgstr "Запись DVD+RW" msgid "Write DVD-RAM" msgstr "Запись DVD-RAM" msgid "Mount Rainier" msgstr "Пакетная запись (Mount Rainier)" msgid "Burn Proof" msgstr "Защита от записи" msgid "Disc info" msgstr "Информация о диске" msgid "This CD does not contain CD-Text information." msgstr "Этот CD не содержит информации CD-Text." msgid "drive" msgstr "диск" msgid "drives" msgstr "диски" msgid "record" msgstr "запись" msgid "records" msgstr "записи" msgid "Add to playlist" msgstr "Добавить в плей-лист" msgid "Add to playlist (Album mode)" msgstr "Добавить в плей-лист (режим альбома)" msgid "CDDB query for this CD..." msgstr "Запрос CDDB для этого CD..." msgid "Submit CD to CDDB database..." msgstr "Отправить данные об этом CD в базу данных CDDB..." msgid "Rip CD..." msgstr "Извлечение музыки с CD..." msgid "Disc info..." msgstr "Информация о диске..." msgid "Drive info..." msgstr "Информация о диске..." msgid "Comments:" msgstr "Комментарии:" msgid "Please select the xml file for this store." msgstr "Выберите, пожалуйста, xml-файл для этой библиотеки." msgid "Create empty store" msgstr "Создать пустую библиотеку" msgid "Visible name:" msgstr "Выводимое имя:" msgid "Edit Store" msgstr "Редактировать библиотеку" msgid "Use relative paths in store file" msgstr "Использовать относительные пути в файле библиотеки" msgid "Add Artist" msgstr "Добавить исполнителя" msgid "Name to sort by:" msgstr "Имя для сортировки:" msgid "Edit Artist" msgstr "Редактировать исполнителя" msgid "Please select the audio files for this record." msgstr "Пожалуйста, выберите аудиофайлы для этой записи." msgid "Add Record" msgstr "Добавить запись" msgid "Auto-create tracks from these files:" msgstr "Автоматически создать треки из этих файлов:" msgid "_Add files..." msgstr "_Добавить файлы..." msgid "Edit Record" msgstr "Редактировать запись" msgid "Please select the audio file for this track." msgstr "Пожалуйста, выберите аудиофайл для этого трека." msgid "Add Track" msgstr "Добавить трек" msgid "Edit Track" msgstr "Редактировать трек" msgid "Duration:" msgstr "Продолжительность:" #, c-format msgid "Unmeasured" msgstr "Неизмеренный" msgid "Volume level:" msgstr "Уровень громкости:" msgid "Use manual RVA value [dB]" msgstr "Использовать свой уровень RVA [дБ]" #, c-format msgid "Really remove \"%s\" from the Music Store?" msgstr "Действительно удалить \"%s\" из музыкальной библиотеки?" msgid "Stop adding songs" msgstr "Остановить добавление песен" #, c-format msgid "" "The store '%s' already exists.\n" "Add it on the Settings/Music Store tab." msgstr "" "Библиотека '%s' уже существует.\n" "Добавьте её на вкладке Настройки/Музыкальная Библиотека." #, c-format msgid "Really remove store \"%s\" from the Music Store?" msgstr "Действительно удалить библиотеку \"%s\" из Музыкальной библиотеки?" msgid "Remove Store" msgstr "Удалить библиотеку" msgid "Do you want to save the store before removing?" msgstr "Хотите сохранить библиотеку перед удалением?" msgid "Remove Artist" msgstr "Удалить исполнителя" msgid "Remove Record" msgstr "Удалить запись" msgid "Remove Track" msgstr "Удалить трек" msgid "Update file metadata" msgstr "Обновить метаданные файла" msgid "Track name" msgstr "Имя трека" msgid "Track comment" msgstr "Комментарий к треку" msgid "Track number" msgstr "Номер трека" msgid "Failed to set metadata for the following files:" msgstr "Невозможно установить метаданные для следующих файлов:" msgid "Filename" msgstr "Имя файла" msgid "Reason" msgstr "Причина" msgid "(no comment)" msgstr "(нет комментария)" msgid "artist" msgstr "исполнитель" msgid "artists" msgstr "исполнители" #, c-format msgid "File \"%s\" does not exist or your write permission has been withdrawn. Check if the partition containing the store file has been unmounted." msgstr "Файл \"%s\" не существует или у вас нет прав записи в него. Проверьте, не отмонтирован ли раздел, на котором расположен файл библиотеки." msgid "Build / Update store from filesystem..." msgstr "Построить / Обновить библиотеку из файловой системы..." msgid "Edit store..." msgstr "Редактировать библиотеку..." msgid "Export store..." msgstr "Экспорт библиотеки..." msgid "Save store" msgstr "Сохранить библиотеку" msgid "Remove store" msgstr "Удалить библиотеку" msgid "Add new artist to this store..." msgstr "Добавить нового исполнителя в эту библиотеку..." msgid "Calculate volume (recursive)" msgstr "Вычислить громкость (рекурсивно)" msgid "Unmeasured tracks only" msgstr "Только неизмеренные треки" msgid "All tracks" msgstr "Все треки" msgid "Batch-update file metadata..." msgstr "Пакетное обновление метаданных файла..." msgid "Add new artist..." msgstr "Добавить нового исполнителя..." msgid "Edit artist..." msgstr "Редактировать исполнителя..." msgid "Export artist..." msgstr "Экспортировать исполнителя..." msgid "Remove artist" msgstr "Удалить исполнителя" msgid "Add new record to this artist..." msgstr "Добавить новую запись этого исполнителя..." msgid "Add new record..." msgstr "Добавить новую запись..." msgid "Edit record..." msgstr "Редактировать запись..." msgid "Export record..." msgstr "Экспортировать запись..." msgid "Remove record" msgstr "Удалить запись" msgid "Add new track to this record..." msgstr "Добавить новый трек в эту запись..." msgid "CDDB query for this record..." msgstr "Запрос CDDB для этой записи..." msgid "Submit record to CDDB database..." msgstr "Отправить запись в базу данных CDDB..." msgid "Add new track..." msgstr "Добавить новый трек..." msgid "Edit track..." msgstr "Редактировать трек..." msgid "Export track..." msgstr "Экспорт трека..." msgid "Remove track" msgstr "Удалить трек" msgid "Calculate volume" msgstr "Рассчитать громкость" msgid "Only if unmeasured" msgstr "Только если измерен" msgid "In any case" msgstr "В любом случае" msgid "Update file metadata..." msgstr "Обновить метаданные файла..." msgid "Please select the download directory for this podcast." msgstr "Пожалуйста, выберите каталог загрузки для этого подкаста." msgid "Subscribe to new feed" msgstr "Подписаться на новую ленту" msgid "Edit feed settings" msgstr "Редактировать свойства ленты" msgid "Podcast URL:" msgstr "URL подкаста:" msgid "Download directory:" msgstr "Каталог загрузки:" msgid "Auto-check interval [hour]:" msgstr "Интервал автопроверки [час]:" msgid "" "Automatic update has been disabled for all feeds\n" "in the Podcasts store popup menu." msgstr "" "Автоматическое обновление запрещено для всех лент\n" "во всплывающем меню базы подкастов." msgid "Limits" msgstr "Пределы" msgid "Maximum number of items:" msgstr "Максимальное число элементов:" msgid "Remove older items [day]:" msgstr "Удалить устаревшие элементы [день]:" msgid "Maximum space to use [MB]:" msgstr "Максимальное используемое пространство [Мб]:" msgid "Podcasts" msgstr "Подкасты" msgid "Updating..." msgstr "Обновление..." msgid "Delete downloaded items from the filesystem" msgstr "Удалить загруженные элементы из файловой системы" msgid "Remove feed" msgstr "Удалить ленту" #, c-format msgid "Really remove '%s' from the Music Store?" msgstr "Действительно удалить '%s' из Музыкальной Библиотеки?" msgid "Reorder feeds" msgstr "Изменить порядок лент" msgid "" "Drag and drop entries in the list\n" "to set the feed order in the Music Store." msgstr "" "Перетащите содержимое в списке,\n" "чтобы установить порядок лент в Музыкальной Библиотеке." #, c-format msgid "Downloading %d/%d (%d%%) ..." msgstr "Загрузка %d/%d (%d%%) ..." msgid "item" msgstr "элемент" msgid "items" msgstr "элементы" msgid "new item" msgstr "новый элемент" msgid "new items" msgstr "новые элементы" msgid "feed" msgstr "лента" msgid "feeds" msgstr "ленты" msgid "Export item..." msgstr "Экспорт элемента..." msgid "Add all items to playlist" msgstr "Добавить все элементы в плей-лист" msgid "Add all items to playlist (Album mode)" msgstr "Добавить все элементы в плей-лист (режим альбома)" msgid "Add new items to playlist" msgstr "Добавить новые элементы в плей-лист" msgid "Add new items to playlist (Album mode)" msgstr "Добавить в плей-лист (режим альбома)" msgid "Edit feed" msgstr "Редактировать ленту" msgid "Export all items..." msgstr "Экспорт всех элементов..." msgid "Export new items..." msgstr "Экспорт новых элементов..." msgid "Update feed" msgstr "Обновить ленту" msgid "Abort ongoing update" msgstr "Прервать текущее обновление" msgid "Update all feeds" msgstr "Обновить все ленты" msgid "Automatically update feeds" msgstr "Автоматически обновлять ленты" msgid "Unexpected end of string after '?'." msgstr "Неожиданный конец строки после '?'." msgid "Expected '}' after '{', but end of string found." msgstr "Ожидалось '}' после '{', а найден конец строки." #, c-format msgid "Unknown conversion type character found after '%%%%'." msgstr "После '%%%%' обнаружен символ неизвестного типа." msgid "Unknown conversion type character found after '?'." msgstr "После '?' обнаружен символ неизвестного типа." msgid "day" msgstr "день" msgid "days" msgstr "дни" msgid "All Files" msgstr "Все файлы" msgid "Extended Title Format Files (*.lua)" msgstr "Файлы расширенного форматирования заголовка (*.lua)" msgid "Music Store Files (*.xml)" msgstr "Файлы музыкальной библиотеки (*.xml)" msgid "Aqualung playlist (*.xml)" msgstr "Плей-лист Aqualung (*.xml)" msgid "MP3 Playlist (*.m3u)" msgstr "Плей-лист MP3 (*.m3u)" msgid "Multimedia Playlist (*.pls)" msgstr "Мультимедиа плей-лист (*.pls)" msgid "All Playlist Files" msgstr "Все файлы плей-листа" msgid "All Audio Files" msgstr "Все аудио файлы" msgid "Sound Files (*.wav, *.aiff, *.au, ...)" msgstr "Звуковые файлы (*.wav, *.aiff, *.au, ...)" msgid "Free Lossless Audio Codec (*.flac)" msgstr "Free Lossless Audio Codec (*.flac)" msgid "MPEG Audio (*.mp3, *.mpa, *.mpega, ...)" msgstr "MPEG Audio (*.mp3, *.mpa, *.mpega, ...)" msgid "Ogg Vorbis (*.ogg)" msgstr "Ogg Vorbis (*.ogg)" msgid "Ogg Speex (*.spx)" msgstr "Ogg Speex (*.spx)" msgid "Musepack (*.mpc)" msgstr "Musepack (*.mpc)" msgid "Monkey's Audio Codec (*.ape)" msgstr "Monkey's Audio Codec (*.ape)" msgid "Modules (*.xm, *.mod, *.it, *.s3m, ...)" msgstr "Модули (*.xm, *.mod, *.it, *.s3m, ...)" msgid "Compressed modules (*.gz, *.bz2)" msgstr "Сжатые модули (*.gz, *.bz2)" msgid "Compressed modules (*.gz)" msgstr "Сжатые модули (*.gz)" msgid "Compressed modules (*.bz2)" msgstr "Сжатые модули (*.bz2)" msgid "WavPack (*.wv)" msgstr "WavPack (*.wv)" msgid "LAVC audio/video files" msgstr "Аудио/видео файлы LAVC" msgid "Resume" msgstr "Возобновить" msgid "Calculating volume level" msgstr "Расчет уровня громкости" msgid "Profile: Telephone" msgstr "Профиль: Телефон" msgid "Profile: Thumb" msgstr "Профиль: Эскиз" msgid "Profile: Radio" msgstr "Профиль: Радио" msgid "Profile: Standard" msgstr "Профиль: Стандарт" msgid "Profile: Xtreme" msgstr "Профиль: Экстремальный" msgid "Profile: Insane" msgstr "Профиль: Сумасшедший" msgid "Profile: Braindead" msgstr "Профиль: Без башни" msgid "Layer I" msgstr "Слой I" msgid "Layer II" msgstr "Слой II" msgid "Layer III" msgstr "Слой III" msgid "Unrecognized" msgstr "Не распознано" msgid "Single channel" msgstr "Один канал" msgid "Dual channel" msgstr "Два канала" msgid "Joint stereo" msgstr "объедидённое стерео" msgid "Stereo" msgstr "Стерео" msgid "Emphasis: none" msgstr "Выделение: нет" msgid "Emphasis:" msgstr "Выделение:" msgid "Emphasis: reserved" msgstr "Выделение: зарезервировано" msgid "bit signed" msgstr "бит знаковый" msgid "bit unsigned" msgstr "бит беззнаковый" msgid "bit float" msgstr "бит с плавающей точкой" msgid "bit double" msgstr "бит двойной" msgid "encoding" msgstr "кодирование" msgid "Compression: Fast" msgstr "Сжатие: Быстрое" msgid "Compression: Normal" msgstr "Сжатие: Нормальное" msgid "Compression: High" msgstr "Сжатие: Сильное" msgid "Compression: Extra High" msgstr "Сжатие: Очень сильное" msgid "Compression: Insane" msgstr "Сжатие: Неимоверное" #~ msgid "Directory:" #~ msgstr "Каталог." aqualung-0.9beta11/src/po/sv.po0000644000175000001440000017134411331334210013310 00000000000000msgid "" msgstr "" "Project-Id-Version: Aqualung svn version 1055\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2009-01-20 09:36+0100\n" "PO-Revision-Date: 2009-01-21 15:42+0100\n" "Last-Translator: \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Poedit-Language: Swedish\n" "X-Poedit-Country: SWEDEN\n" msgid "About" msgstr "Om" msgid "Build version: " msgstr "Byggversion:" msgid "Homepage:" msgstr "Webbsida:" msgid "Authors:" msgstr "Upphovsmän:" msgid "Core design, engineering & programming:\n" msgstr "Grundläggande formgivning, konstruktion & programmering:\n" msgid "Skin support, look & feel, GUI hacks:\n" msgstr "Skalstöd, utseende & känsla samt GUI hacks (gags-hack):\n" msgid "Programming, GUI engineering:\n" msgstr "Programmering & GUI engineering (gags-konstruktion):\n" msgid "OpenBSD compatibility, metadata tweaks:\n" msgstr "OpenBSD-kompatibilitet & metadata-finjusteringar:\n" msgid "Translators:" msgstr "Översättare:" msgid "German:\n" msgstr "Tyska:\n" msgid "Hungarian:\n" msgstr "Ungerska:\n" msgid "Italian:\n" msgstr "Italienska:\n" msgid "Russian:\n" msgstr "Ryska:\n" msgid "Ukrainian:\n" msgstr "Ukrainska:\n" msgid "Graphics:" msgstr "Grafik:" msgid "Logo, icons:\n" msgstr "Logotyp och ikoner:\n" msgid "This Aqualung binary is compiled with:" msgstr "Denna Aqualung-binär är kompilerad med:" msgid "Optional features:" msgstr "Valbara funktioner:" msgid "LADSPA plugin support\n" msgstr "Stöd för LADSPA-insticksmodul\n" msgid "CDDA (Audio CD) support\n" msgstr "Stöd för CDDA (ljud-cd)\n" msgid "CDDB support\n" msgstr "CDDB-stöd\n" msgid "Sample Rate Converter support\n" msgstr "Stöd för samplingsfrekvenskonverterare\n" msgid "iRiver iFP driver support\n" msgstr "Stöd för iRiver iFP-drivrutin\n" msgid "Loop playback support\n" msgstr "" msgid "Systray support\n" msgstr "Stöd för systembricka\n" msgid "Podcast support\n" msgstr "Stöd för poddsändning\n" msgid "Lua (programmable title formatting) support\n" msgstr "Stöd för Lua (programmeringsbar titelformatering)\n" msgid "Decoding support:" msgstr "Avkodningsstöd:" msgid "sndfile (WAV, AIFF, etc.)\n" msgstr "sndfile (WAV, AIFF, etc.)\n" msgid "Free Lossless Audio Codec (FLAC)\n" msgstr "Free Lossless Audio Codec (FLAC)\n" msgid "Ogg Vorbis\n" msgstr "Ogg Vorbis\n" msgid "Ogg Speex\n" msgstr "Ogg Speex\n" msgid "MPEG Audio (MPEG 1-2.5 Layer I-III)\n" msgstr "MPEG Audio (MPEG 1-2.5 Layer I-III)\n" msgid "MOD Audio (MOD, S3M, XM, IT, etc.)\n" msgstr "MOD Audio (MOD, S3M, XM, IT, etc.)\n" msgid "Musepack\n" msgstr "Musepack\n" msgid "Monkey's Audio Codec\n" msgstr "Monkey's Audio Codec\n" msgid "WavPack\n" msgstr "WavPack\n" msgid "LAVC (AC3, AAC, WavPack, WMA, etc.)\n" msgstr "LAVC (AC3, AAC, WavPack, WMA, etc.)\n" msgid "Encoding support:" msgstr "kodningsstöd:" msgid "sndfile (WAV)\n" msgstr "sndfile (WAV)\n" msgid "LAME (MP3)\n" msgstr "LAME (MP3)\n" msgid "Output driver support:" msgstr "" msgid "sndio Audio\n" msgstr "sndio Audio\n" msgid "OSS Audio\n" msgstr "OSS Audio\n" msgid "ALSA Audio\n" msgstr "ALSA Audio\n" msgid "JACK Audio Server\n" msgstr "JACK Audio Server\n" msgid "Win32 Sound API\n" msgstr "Win32 Sound API\n" msgid "" "This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.\n" "\n" "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.\n" "\n" "You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." msgstr "" "Följande text är en informell översättning som enbart tillhandahålls i informativt syfte. För alla juridiska tolkningar gäller den engelska originaltexten.\n" "\n" "Detta program är fri programvara. Du kan distribuera det och/eller modifiera det under villkoren i GNU General Public License, publicerad av Free Software Foundation, antingen version 2 eller (om du så vill) någon senare version.\n" "\n" "Detta program distribueras i hopp om att det ska vara användbart, men UTAN NÅGON SOM HELST GARANTI, även utan underförstådd garanti om SÄLJBARHET eller LÄMPLIGHET FÖR NÅGOT SPECIELLT ÄNDAMÅL. Se GNU General Public License för ytterligare information.\n" "\n" "Du bör ha fått en kopia av GNU General Public License tillsammans med detta program. Om inte, skriv till Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." msgid "Enabled" msgstr "Aktiverad" msgid "Source" msgstr "Källa" msgid "CDDB" msgstr "CDDB" msgid "CDDB (not available)" msgstr "CDDB (inte tillgänglig)" msgid "Metadata" msgstr "Metadata" msgid "Filesystem" msgstr "Filsystem" msgid "Capitalization" msgstr "Versalisering" msgid "Capitalize: " msgstr "Versalisera:" msgid "All words" msgstr "Alla ord" msgid "First word only" msgstr "Bara första ordet" msgid "Force case: " msgstr "" msgid "Force other letters to lowercase" msgstr "Tvinga andra bokstäver att skrivas i små bokstäver" msgid "Regular expression" msgstr "Reguljärt uttryck" msgid "Regexp:" msgstr "" msgid "Replace:" msgstr "Ersätt:" msgid "Predefined transformations" msgstr "" msgid "Remove file extension" msgstr "Ta bort filändelse" msgid "Remove leading number" msgstr "" msgid "Convert underscore to space" msgstr "Konvertera understreck till mellanslag" msgid "Trim leading, tailing and duplicate spaces" msgstr "" msgid "Regexp matches empty string" msgstr "" msgid "Please select the root directory." msgstr "Var god välj rootkatalogen." msgid "Select build type" msgstr "" msgid "Directory driven" msgstr "" msgid "" "Follows the directory structure to identify the artists and\n" "records. The files are added on a record basis." msgstr "" "Följer katalogstrukturen för att identifiera artisterna och\n" "skivorna. The files are added on a record basis." msgid "Independent" msgstr "Oberoende" msgid "" "Recursive search from the root directory for audio files.\n" "The files are processed independently, so only metadata\n" "and filename transformation are available." msgstr "" msgid "Load settings from Music Store file" msgstr "Läs in inställningar från musikbiblioteksfil" msgid "Build/Update store" msgstr "Bygg/uppdatera bibliotek" msgid "General" msgstr "Allmänt" msgid "Directory structure" msgstr "Katalogstruktur" msgid "Root path:" msgstr "Sökväg för root:" msgid "_Browse..." msgstr "_Bläddra..." msgid "Structure:" msgstr "Struktur:" msgid "root / record / track" msgstr "root / skiva / spår" msgid "root / artist / record / track" msgstr "root / artist / skiva / spår" msgid "root / artist / artist / record / track" msgstr "root / artist / artist / skiva / spår" msgid "root / artist / artist / artist / record / track" msgstr "root / artist / artist / artist / skiva / spår" msgid "Exclude files matching wildcard" msgstr "Exkludera filer som matchar jokertecken" msgid "Include only files matching wildcard" msgstr "Inkludera bara filer som matchar jokertecken" msgid "Reread data for existing tracks" msgstr "Läs om data för existerande spår" msgid "Remove non-existing files from store" msgstr "Ta bort icke-existerande filer från bibliotek" msgid "Artist" msgstr "Artist" msgid "Sort artists by" msgstr "Sortera artister efter" msgid "Artist name" msgstr "Artistnamn" msgid "Artist name (lowercase)" msgstr "Artistnamn (små bokstäver)" msgid "Directory name" msgstr "Katalognamn" msgid "Directory name (lowercase)" msgstr "Katalognamn (små bokstäver)" msgid "Record" msgstr "Skiva" msgid "Sort records by" msgstr "Sortera skivor efter" msgid "Record name" msgstr "Skivnamn" msgid "Record name (lowercase)" msgstr "Skivnamn (små bokstäver)" msgid "Year" msgstr "År" msgid "Add year to the comments of new records" msgstr "Lägg till år till kommentarer av nya skivor" msgid "Track" msgstr "Spår" msgid "Import Replaygain tag as manual RVA" msgstr "Importera tagg för uppspelningsförstärkning som manuell RVA" msgid "Import Comment tag" msgstr "Importera kommentartagg" msgid "Sandbox" msgstr "" msgid "Filename:" msgstr "Filnamn:" msgid "Test" msgstr "" msgid "Building store from filesystem" msgstr "Bygger musikbibliotek från filsystem" msgid "Processing:" msgstr "Behandlar:" msgid "Action:" msgstr "Åtgärd:" msgid "Abort" msgstr "Avbryt" msgid "Unknown Artist" msgstr "Okänd artist" msgid "Unknown Record" msgstr "Okänd skiva" msgid "Scanning files" msgstr "Söker av filer" msgid "Processing metadata" msgstr "Behandlar metadata" msgid "CDDB lookup" msgstr "CDDB-letar" msgid "Name transformation" msgstr "" msgid "Reading file" msgstr "Läser fil" msgid "Removing non-existing files" msgstr "Tar bort icke-existerande filer" msgid "Unknown disc" msgstr "Okänd disk" msgid "No disc" msgstr "Ingen disk" msgid "CDDB query" msgstr "CDDB-fråga" msgid "Retrieving matches from server..." msgstr "" msgid "Connecting to CDDB server..." msgstr "Ansluter till CDDB-server..." msgid "Error" msgstr "Fel" msgid "An error occurred while attempting to connect to the CDDB server." msgstr "Ett fel inträffade vid försök att ansluta till CDDB-servern." msgid "Warning" msgstr "Varning" msgid "No matching record found." msgstr "Ingen matchande skiva hittades." msgid "Import as Sort Key" msgstr "" msgid "Import as Title" msgstr "Importera som Titel" msgid "Import as Year" msgstr "Importera som År" msgid "" "Artist appears to be in all lowercase.\n" "Do you want to proceed?" msgstr "" "Artistnamnet ser ut att bara bestå av små bokstäver.\n" "Vill du fortsätta?" msgid "" "Artist appears to be in all uppercase.\n" "Do you want to proceed?" msgstr "" "Artistnamnet ser ut att bara bestå av stora bokstäver.\n" "Vill du fortsätta?" msgid "" "Title appears to be in all lowercase.\n" "Do you want to proceed?" msgstr "" "Titeln ser ut att bara bestå av små bokstäver.\n" "Vill du fortsätta?" msgid "" "Title appears to be in all uppercase.\n" "Do you want to proceed?" msgstr "" "Titeln ser ut att bara bestå av stora bokstäver.\n" "Vill du fortsätta?" msgid "" "It is very likely that the year is wrong.\n" "Do you want to proceed?" msgstr "" "Det är väldigt troligt att året är fel.\n" "Vill du fortsätta?" msgid "The email address provided for submission is invalid." msgstr "E-postadressen som tillhandahölls för uppladdning är ogiltig." msgid "An error occurred while submitting the record to the CDDB server." msgstr "Ett fel inträffade då skivan skulle skickas in till CDDB-servern." msgid "Correct existing record" msgstr "Rätta existerande skiva" msgid "Submit new record" msgstr "Skicka in ny skiva" msgid "Matches:" msgstr "" msgid "Artist:" msgstr "Artist:" msgid "Title:" msgstr "Titel:" msgid "Year:" msgstr "År" msgid "Category:" msgstr "Kategori:" msgid "(choose a category)" msgstr "(välj en kategori)" msgid "Genre:" msgstr "Genre:" msgid "Extended data:" msgstr "Utökat data:" msgid "Import as Artist" msgstr "Importera som Artist" msgid "Add to Comments" msgstr "Lägg till i kommentarer" msgid "Tracks" msgstr "Spår" msgid "You have to provide an email address for CDDB submission." msgstr "Du måste tillhandahålla en e-postadress för att ladda upp till CDDB." msgid "Please select the directory for ripped files." msgstr "Var god ange katalogen för extraherade filer." msgid "(none)" msgstr "(ingen)" msgid "fast" msgstr "snabb" msgid "best" msgstr "bäst" msgid "Compression level:" msgstr "Komprimeringsnivå:" msgid "Bitrate [kbps]:" msgstr "Bithastighet [kbps]:" msgid "Artist/Album already existing, not empty" msgstr "Artist/album finns redan, inte tomt" msgid "" "\n" "The Music Store you selected has a matching Artist and Album, already containing some tracks. If you press OK, these tracks will be removed. The files themselves will be left intact, but they will be removed from the destination Music Store. Press Cancel to get back to change the Artist/Album or the destination Music Store." msgstr "" "\n" "Musikbiblioteket som du markerade har en matchande artist och album vilket redan innehåller några spår. Om du trycker OK kommer dessa spår att tas bort. Själva filerna kommer att lämnas intakta, men de kommer att tas bort från musikbiblioteket. Tryck Avbryt för att gå tillbaka och ändra Artist/Album eller musikbibliotek." msgid "Rip CD" msgstr "Extrahera cd" msgid "Album:" msgstr "Album:" msgid "Rip" msgstr "Extrahera" msgid "No." msgstr "Nej." msgid "Title" msgstr "Titel" msgid "Select" msgstr "Välj" msgid "All" msgstr "Alla" msgid "None" msgstr "Ingen" msgid "Output" msgstr "Utdata" msgid "Destination" msgstr "" msgid "Target directory for ripped files" msgstr "Målkatalog för extraherade filer" msgid "Add to Music Store" msgstr "Lägg till i musikbibliotek" msgid "Format" msgstr "Format" msgid "File format:" msgstr "Filformat:" msgid "VBR encoding" msgstr "VBR-kodning" msgid "Tag files with metadata" msgstr "Tagga filer med metadata" msgid "Paranoia" msgstr "Paranoia" msgid "Paranoia error correction" msgstr "Paranoiafelkorrigering" msgid "Perform overlapped reads" msgstr "" msgid "Verify data integrity" msgstr "Bekräfta dataintegritet" msgid "Unlimited retry on failed reads (never skip)" msgstr "" msgid "Maximum number of retries:" msgstr "Maximala antalet återförsök:" msgid "" "\n" "Destination directory is not read-write accessible!" msgstr "" msgid "Total" msgstr "Totalt" msgid "(audio only)" msgstr "(bara ljud)" msgid "Ripping CD tracks" msgstr "Extraherar cd-spår" msgid "Begin" msgstr "Börja" msgid "Length" msgstr "Speltid" msgid "Progress" msgstr "Förlopp" msgid "Close window when complete" msgstr "Stäng fönstret när det är klart" msgid "Close" msgstr "Stäng" msgid "Unknown Album" msgstr "Okänt album" msgid "Unknown Track" msgstr "Okänt spår" msgid "Please select the directory for exported files." msgstr "Var god ange katalogen för exporterade filer." msgid "Copy" msgstr "Kopia" msgid "Help" msgstr "Hjälp" #, c-format msgid "" "\n" "The template string you enter here will be used to construct the filename of the exported files. The Artist, Record and Track names are denoted by %%%%a, %%%%r and %%%%t. The track number and format-dependent file extension are denoted by %%%%n and %%%%x, respectively. The flag %%%%i gives an identifier which is unique within an export session." msgstr "" "\n" "Strängmallen som du skriver in här kommer att användas för att konstruera filnamnet på de exporterade filerna. Artist-, skiv- och spårnamnen kommer att betecknas med %%%%a, %%%%r och %%%%t. The track number and format-dependent file extension are denoted by %%%%n and %%%%x, respectively. The flag %%%%i gives an identifier which is unique within an export session." msgid "Export files" msgstr "Exportera filer" msgid "Location and filename" msgstr "Plats och filnamn" msgid "Target directory:" msgstr "Målkatalog:" msgid "Create subdirectories for artists" msgstr "Skapa underkataloger för artister" msgid "Create subdirectories for albums" msgstr "Skapa underkataloger för album" msgid "" "Subdirectory name\n" "length limit:" msgstr "" msgid "Filename template:" msgstr "Filnamnsmall:" msgid "Filter" msgstr "Filter" msgid "Do not reencode files already being in the target format" msgstr "Koda inte om filer som redan är i målformatet" msgid "" "Do not reencode files\n" "matching wildcard:" msgstr "" "Koda inte om filer\n" "som machar jokertecken:" msgid "Error in format string" msgstr "Fel i formatsträng" msgid "Exporting files" msgstr "Exporterar filer" msgid "Source file:" msgstr "Källfil:" msgid "Target file:" msgstr "Målfil:" msgid "Progress:" msgstr "Förlopp:" msgid "*File info" msgstr "*Filinformation" msgid "File info" msgstr "Filinformation" msgid "There are unsaved changes to the file metadata." msgstr "Det finns osparade ändringar till filmetadatat." msgid "Save and close" msgstr "Spara och stäng" msgid "Discard changes" msgstr "Förkasta ändringar" msgid "Do not close" msgstr "Stäng inte" #, c-format msgid "" "Conversion error in field %s:\n" "'%s' does not conform to format '%s'!" msgstr "" msgid "" "Attached Picture frame with no image set!\n" "Please set an image or remove the frame." msgstr "" #, c-format msgid "" "Failed to write metadata to file.\n" "Reason: %s" msgstr "" "Misslyckades med att skriva metadata till fil.\n" "Orsak: %s" #, c-format msgid "" "Error converting field %s to Year:\n" "'%s' is not an integer number!" msgstr "" msgid "Please specify the file to save the image to." msgstr "Var god ange filen som bilden ska sparas till." msgid "(no image)" msgstr "(ingen bild)" msgid "(error loading image)" msgstr "(fel uppstod vid inläsning av bild)" msgid "Please specify the file to load the image from." msgstr "Var god ange filen som bilden ska läsas in från." #, c-format msgid "" "Could not load image from:\n" "%s" msgstr "" "Kunde inte läsa in bild från:\n" "%s" #, c-format msgid "MIME type: %s" msgstr "MIME-typ: %s" msgid "Picture type:" msgstr "Bildtyp:" msgid "Description:" msgstr "Beskrivning:" msgid "(no description)" msgstr "(ingen beskrivning)" msgid "Change" msgstr "Byt" msgid "Save" msgstr "Spara" msgid "Import as Record" msgstr "Importera som Skiva" msgid "Import as Track No." msgstr "Importera som Spårnummer" msgid "Import as RVA" msgstr "Importera som RVA" msgid "Add" msgstr "Lägg till" msgid "field:" msgstr "fält:" msgid "tag:" msgstr "tagg:" msgid "Audio CD" msgstr "Ljud-cd" msgid "Track:" msgstr "Spår:" msgid "File:" msgstr "Fil:" msgid "Audio data" msgstr "Ljuddata" msgid "Format:" msgstr "Format:" msgid "Length:" msgstr "Speltid:" msgid "Samplerate:" msgstr "Samplingsfrekvens:" #, c-format msgid "%ld Hz" msgstr "%ld Hz" msgid "Channel count:" msgstr "Antal kanaler:" msgid "MONO" msgstr "MONO" msgid "STEREO" msgstr "STEREO" msgid "Bandwidth:" msgstr "Bandbredd:" msgid "Total samples:" msgstr "Totalt antal samplingar:" msgid "Mode:" msgstr "Läge:" msgid "Type:" msgstr "Typ:" msgid "Channels:" msgstr "Kanaler:" msgid "Patterns:" msgstr "Mönster:" msgid "Samples:" msgstr "Samplingar:" msgid "Instruments:" msgstr "Instrument:" msgid "Samples" msgstr "Samplingar" msgid "Instruments" msgstr "Instrument" msgid "Name" msgstr "Namn" msgid "Output:" msgstr "Utdata:" msgid "No output" msgstr "Inget utdata" msgid "SRC Type: " msgstr "SRC-typ:" #, c-format msgid "Loop range: %d-%d%% [%s - %s]" msgstr "" #, c-format msgid "Loop range: %d-%d%%" msgstr "" msgid "" "One or more stores in Music Store have been modified.\n" "Do you want to save them before exiting?" msgstr "" "En eller flera bibliotek i musikbiblioteket har modifierats.\n" "Vill du spara dem innan du avslutar?" msgid "Do not exit" msgstr "Avsluta inte" msgid "Quit" msgstr "Avsluta" #, c-format msgid "Position: %d%%" msgstr "Position: %d%%" #, c-format msgid "Mute" msgstr "Tysta" #, c-format msgid "%d dB" msgstr "%d dB" #, c-format msgid "Volume: %s" msgstr "Volym: %s" #, c-format msgid "%d%% R" msgstr "%d%% H" #, c-format msgid "%d%% L" msgstr "%d%% V" #, c-format msgid "C" msgstr "M" #, c-format msgid "Balance: %s" msgstr "Balans: %s" msgid "JACK connection lost" msgstr "JACK-anslutning borttappad" msgid "JACK has either been shutdown or it disconnected Aqualung because it was not fast enough. All you can do now is restart both JACK and Aqualung." msgstr "JACK har antingen stängts av eller så kopplade det från Aqualung för att det inte var tillräckligt snabbt. Det enda du kan göra nu är att starta om både JACK och Aqualung." msgid "Warn me if the Window Manager does not support system tray" msgstr "Varna mig om fönsterhanteraren inte stöder visning av ikon i systembricka" msgid "Aqualung is compiled with system tray support, but the status icon could not be embedded in the notification area. Your desktop may not have support for a system tray, or it has not been configured correctly." msgstr "Aqualung är kompilerat med stöd för ikon i systembricka, men statusikonen kunde inte bäddas in i notifieringsytan. Ditt skrivbord har kanske inte stöd för en systembricka, eller så har den inte konfigurerats på rätt sätt." msgid "Settings" msgstr "Inställningar" msgid "Skin chooser" msgstr "Skalväljare" msgid "JACK port setup" msgstr "JACK-portinställning" msgid "Previous song" msgstr "Föregående låt" msgid "Stop" msgstr "Stoppa" msgid "Next song" msgstr "Nästa låt" msgid "Play/Pause" msgstr "Spela/pausa" msgid "Play" msgstr "Spela" msgid "Pause" msgstr "Pausa" msgid "Repeat current song" msgstr "Upprepa aktuell låt" msgid "Repeat all songs" msgstr "Upprepa alla låtar" msgid "Shuffle songs" msgstr "Blanda låtar" msgid "Toggle playlist" msgstr "Växla spellista" msgid "Toggle music store" msgstr "Växla musikbibliotek" msgid "Toggle LADSPA patch builder" msgstr "" msgid "Show Aqualung" msgstr "Visa Aqualung" msgid "Hide Aqualung" msgstr "Dölj Aqualung" msgid "Previous" msgstr "Föregående" msgid "Next" msgstr "Nästa" #, c-format msgid "%.1f MB / %.1f MB" msgstr "%.1f MB / %.1f MB" #, c-format msgid "%d / %d files" msgstr "%d / %d filer" #, c-format msgid "%d / %d directories" msgstr "%d / %d kataloger" msgid "Cannot write to selected directory. Please select another directory." msgstr "Kan inte skriva till markerad katalog. Var god välj en annan katalog." msgid "Done" msgstr "Klar" msgid "Aborted..." msgstr "Avbruten..." msgid "Please enter directory name." msgstr "Var god skriv in ett katalognamn." msgid "Create directory" msgstr "Skapa katalog" msgid "Please enter a new name." msgstr "Var god skriv in ett namn." msgid "Rename" msgstr "Byt namn" #, c-format msgid "" "Directory '%s' will be removed with its entire contents.\n" "\n" "Do you want to proceed?" msgstr "" "Katalog '%s' kommer att tas bort med hela dess innehåll.\n" "\n" "Vill du fortsätta?" #, c-format msgid "" "File '%s' will be removed.\n" "\n" "Do you want to proceed?" msgstr "" "Fil '%s' kommer att tas bort.\n" "\n" "Vill du fortsätta?" msgid "Remove" msgstr "Ta bort" #, c-format msgid " (%.1f MB)" msgstr " (%.1f MB)" #, c-format msgid " (capacity = %.1f MB)" msgstr "(kapacitet = %.1f MB)" #, c-format msgid " Free space (%.1f MB)" msgstr " Fritt utrymme (%.1f MB)" msgid "" "No suitable iRiver iFP device found.\n" "Perhaps it is unplugged or turned off." msgstr "" "Ingen lämplig iRiver iFP-enhet hittades.\n" "Kanske är den uttagen eller avstängd." msgid "" "Device is busy.\n" "(Aqualung was unable to claim its interface.)" msgstr "" "Enheten är upptagen.\n" "(Aqualung kunde inte nå dess gränssnitt.)" msgid "" "Device is not responding.\n" "Try jiggling the handle." msgstr "" "Enheten svarar inte.\n" "Try jiggling the handle." msgid "Please select a local path." msgstr "Var god välj en lokal sökväg." msgid "Please select at least one valid song from playlist." msgstr "Var god välj minst en giltig låt från spellista." #, c-format msgid "" "One song has format unsupported by your player.\n" "\n" "Do you want to proceed?" msgstr "" "En låt är i ett format som inte stöds av din spelare.\n" "\n" "Vill du fortsätta?" #, c-format msgid "" "%d of %d songs have format unsupported by your player.\n" "\n" "Do you want to proceed?" msgstr "" "%d av %d låtar är i ett format som inte stöds av din spelare.\n" "\n" "Vill du fortsätta?" #, c-format msgid "" "The selected song has format unsupported by your player.\n" "\n" "Do you want to proceed?" msgstr "" "De markerade låtarna är i ett format som inte stöds av din spelare.\n" "\n" "Vill du fortsätta?" #, c-format msgid "" "None of the selected songs has format supported by your player.\n" "\n" "Do you want to proceed?" msgstr "" "Ingen av de markerade låtarna är i ett format som stöds av din spelare.\n" "\n" "Vill du fortsätta?" msgid "iFP device manager (upload mode)" msgstr "iFP-enhetshanterare (uppladdningsläge)" msgid "iFP device manager (download mode)" msgstr "iFP-enhetshanterare (hämtningsläge)" msgid "Selected files:" msgstr "Markerade filer:" msgid "label_songs" msgstr "" msgid "Songs info" msgstr "Information om låtar" msgid "Model:" msgstr "Modell:" msgid "Battery" msgstr "Batteri" msgid "Free space" msgstr "Fritt utrymme" msgid "Device status" msgstr "Enhetsstatus" msgid "Size" msgstr "Storlek" msgid "Create a new directory" msgstr "Skapa en ny katalog" msgid "Remote directory" msgstr "Fjärrkatalog" msgid "Local directory" msgstr "Lokal katalog" msgid "Browse" msgstr "Bläddra" msgid "File name: " msgstr "Filnamn:" msgid "Current file: " msgstr "Aktuell fil:" msgid "Overall: " msgstr "" msgid "Idle" msgstr "Inaktiv" msgid "Transfer progress" msgstr "Överföringsförlopp" msgid "Close window when transfer complete" msgstr "Stäng fönster då överföring är klar" msgid "_Upload" msgstr "_Skicka" msgid "_Download" msgstr "_Hämta" msgid "_Abort" msgstr "_Avbryt" msgid "Success" msgstr "Succé" msgid "Memory allocation error" msgstr "Minnesallokeringsfel" msgid "Unable to open file" msgstr "Kan inte öppna fil" msgid "No metadata support for this format" msgstr "Inget metadata stöder detta format" msgid "File is not writable" msgstr "Filen är inte skrivbar" msgid "Invalid 'Track no.' field value" msgstr "Fältet 'Spårnummer' har ett ogiltigt värde" msgid "Invalid 'Genre' field value" msgstr "Fältet 'Genre' har ett ogiltigt värde" msgid "Conversion to target charset failed" msgstr "" msgid "Internal error" msgstr "Internt fel" msgid "Unknown error" msgstr "Okänt fel" msgid "Album" msgstr "Album" msgid "Date" msgstr "Datum" msgid "Genre" msgstr "Genre" msgid "Track No." msgstr "Spårnummer" msgid "Comment" msgstr "Kommentar" msgid "Disc" msgstr "Disk" msgid "Performer" msgstr "Sångare" msgid "Description" msgstr "Beskrivning" msgid "Organization" msgstr "Organisation" msgid "Location" msgstr "Plats" msgid "Contact" msgstr "Kontakt" msgid "License" msgstr "Licens" msgid "Copyright" msgstr "Copyright" msgid "ISRC" msgstr "ISRC" msgid "Version" msgstr "Version" msgid "Subtitle" msgstr "" msgid "Debut Album" msgstr "Debutalbum" msgid "Publisher" msgstr "Utgivare" msgid "Conductor" msgstr "Dirigent" msgid "Composer" msgstr "Kompositör" msgid "Publication Right" msgstr "" msgid "File" msgstr "Fil" msgid "EAN/UPC" msgstr "EAN/UPC" msgid "ISBN" msgstr "ISBN" msgid "Catalog Number" msgstr "Katalognummer" msgid "Label Code" msgstr "Etikett-id" msgid "Record Date" msgstr "Inspelningsdatum" msgid "Record Location" msgstr "Inspelningsplats" msgid "Media" msgstr "" msgid "Index" msgstr "" msgid "Related" msgstr "" msgid "Abstract" msgstr "" msgid "Language" msgstr "Språk" msgid "Bibliography" msgstr "Bibliografi" msgid "Introplay" msgstr "" msgid "BPM" msgstr "BPM" msgid "Encoding Time" msgstr "Kodningstid" msgid "Playlist Delay" msgstr "Spellistefördröjning" msgid "Original Release Time" msgstr "Ursprungligt utgivningsdatum" msgid "Release Time" msgstr "Utgivningsdatum" msgid "Tagging Time" msgstr "Taggningstid" msgid "Encoded by" msgstr "Kodad av" msgid "Lyricist/Text Writer" msgstr "Låtskrivare/textskrivare" msgid "File Type" msgstr "Filtyp" msgid "Involved People" msgstr "Involverade personer" msgid "Content Group" msgstr "" msgid "Initial key" msgstr "" msgid "Musician Credits" msgstr "" msgid "Mood" msgstr "Stämning" msgid "Original Album" msgstr "Ursprungligt album" msgid "Original Filename" msgstr "Ursprungligt filnamn" msgid "Original Lyricist" msgstr "Ursprunglig låtskrivare" msgid "Original Artist" msgstr "Ursprunglig artist" msgid "File Owner" msgstr "Filägare" msgid "Band/Orchestra" msgstr "Band/orkester" msgid "Interpreted/Remixed" msgstr "Tolkad/remixad" msgid "Part Of A Set" msgstr "" msgid "Produced" msgstr "Producerad" msgid "Internet Radio Station Name" msgstr "Namn på internetradiostation" msgid "Internet Radio Station Owner" msgstr "Ägare till internetradiostation" msgid "Album Sort Order" msgstr "" msgid "Performer Sort Order" msgstr "" msgid "Title Sort Order" msgstr "" msgid "Software" msgstr "Programvara" msgid "Set Subtitle" msgstr "" msgid "User Defined Text" msgstr "" msgid "Commercial Information" msgstr "Kommersiell information" msgid "Copyright/Legal Information" msgstr "Copyright/juridisk information" msgid "Official Audio File Website" msgstr "Ljudfilens officiella webbsida" msgid "Official Artist Website" msgstr "Artistens officiella webbsida" msgid "Official Audio Source Website" msgstr "Ljudkällans officiella webbsida" msgid "Official Radio Station Website" msgstr "Radiostationens officiella webbsida" msgid "Payment" msgstr "Betalning" msgid "Publisher's Official Website" msgstr "Utgivarens officiell webbsida" msgid "User Defined URL" msgstr "" msgid "Vendor" msgstr "Tillverkare" msgid "ReplayGain Reference Loudness" msgstr "" msgid "ReplayGain Track Gain" msgstr "" msgid "ReplayGain Track Peak" msgstr "" msgid "ReplayGain Album Gain" msgstr "" msgid "ReplayGain Album Peak" msgstr "" msgid "Icy-Name" msgstr "" msgid "Icy-Description" msgstr "" msgid "Icy-Genre" msgstr "" msgid "RVA" msgstr "RVA" msgid "Attached Picture" msgstr "Bifogad bild" msgid "Binary Object" msgstr "Binärt objekt" msgid "NULL" msgstr "NULL" msgid "ID3v1" msgstr "ID3v1" msgid "ID3v2" msgstr "ID3v2" msgid "APE" msgstr "APE" msgid "Ogg Xiph Comments" msgstr "Ogg Xiph-kommentarer" msgid "FLAC Pictures" msgstr "FLAC-bilder" msgid "Musepack ReplayGain" msgstr "" msgid "Generic StreamMeta" msgstr "" msgid "MPEG StreamMeta" msgstr "" msgid "Module info" msgstr "" msgid "Unknown" msgstr "" msgid "Other" msgstr "" msgid "File icon (32x32 PNG)" msgstr "Filikon (32x32 PNG)" msgid "File icon (other)" msgstr "Filikon (annat)" msgid "Front cover" msgstr "Omslagsbild framsida" msgid "Back cover" msgstr "Omslagsbild baksida" msgid "Leaflet page" msgstr "" msgid "Album image" msgstr "Albumbild" msgid "Lead artist/performer" msgstr "" msgid "Artist/performer" msgstr "Artist/sångare" msgid "Band/orchestra" msgstr "Band/orkester" msgid "Lyricist/text writer" msgstr "Låtskrivare/textskrivare" msgid "Recording location/studio" msgstr "Inspelningsplats/studio" msgid "During recording" msgstr "Under inspelning" msgid "During performance" msgstr "Under framträdande" msgid "Movie/video screen capture" msgstr "" msgid "A large, coloured fish" msgstr "En stor, färgad fisk" msgid "Illustration" msgstr "Illustration" msgid "Band/artist logotype" msgstr "Band/artistlogotyp" msgid "Publisher/studio logotype" msgstr "Utgivare/studiologotyp" msgid "Music Store" msgstr "Musikbibliotek" msgid "Search..." msgstr "Sök..." msgid "Collapse all items" msgstr "Fäll in alla objekt" msgid "Edit item..." msgstr "Redigera objekt..." msgid "Add item..." msgstr "Lägg till objekt..." msgid "Remove item..." msgstr "Ta bort objekt..." msgid "Save all stores" msgstr "Spara alla bibliotek" msgid "Create empty store..." msgstr "Skapa ett tomt bibliotek..." msgid "*Music Store" msgstr "*Musikbibliotek" #, c-format msgid "Do you want to save store \"%s\" before removing from Music Store?" msgstr "Vill du spara bibliotek \"%s\" innan det tas bort från musikbibliotek?" msgid "You will need to restart Aqualung for the following changes to take effect:" msgstr "Du kommer att behöva starta om Aqualung för att de följande ändringarna ska börja gälla:" msgid "Select a font..." msgstr "Välj ett typsnitt..." msgid "Disable skin support" msgstr "Inaktivera skalstöd" msgid "rw" msgstr "läs och skriv" msgid "r" msgstr "skrivskyddad" msgid "unreachable" msgstr "" msgid "Please select a Programable Title Format File." msgstr "Var god välj en programmeringsbar titelformatsfil." msgid "Please select a Music Store database." msgstr "Var god välj en musikbiblioteksdatabas." msgid "Paths must either be absolute or starting with a tilde." msgstr "" msgid "The specified store has already been added to the list." msgstr "Det angivna biblioteket har redan lagts till i listan." #, c-format msgid "" "\n" "The template string you enter here will be used to construct a single title line from an Artist, a Record and a Track name. These are denoted by %%%%a, %%%%r and %%%%t, respectively.\n" msgstr "" "\n" "Strängmallen som du skriver in här kommer att användas för att konstruera en enskild titelrad baserat på ett artist-, skiv- och spårnamn. Dessa betecknas med %%%%a respektive %%%%r och %%%%t.\n" msgid "" "\n" "The file you enter/choose here will set the Lua program to use to format the title. See the Aqualung manual for details. Here is a quick example of what you can use in the file:\n" "\n" "function playlist_title()\n" " return m('artist') .. '-' .. m('title') .. ' (' .. m('album') .. ') (' .. i('filename') .. ')'\n" "end" msgstr "" "\n" "Den fil som du anger/väljer här kommer att användas av Lua-programmet till att formatera titeln. Se Aqualung-manualen för fler detaljer.Här är ett litet exempel på vad du kan skriva i filen:\n" "\n" "function playlist_title()\n" " return m('artist') .. '-' .. m('title') .. ' (' .. m('album') .. ') (' .. i('filename') .. ')'\n" "end" msgid "" "\n" "The string you enter here will be parsed as a command line before parsing the actual command line parameters. What you enter here will act as a default setting and may or may not be overridden from the 'real' command line.\n" "\n" "Example: enter '-o alsa -R' below to use ALSA output running realtime as a default.\n" msgstr "" msgid "" "Paths must either be absolute or starting with a tilde, which will be expanded to the user's home directory.\n" "\n" "Drag and drop entries in the list to set the store order in the Music Store." msgstr "" msgid "" "\n" "Set the drive speed for CD playing in CD-ROM speed units. One speed unit equals to 176 kBps raw data reading speed. Warning: not all drives honor this setting.\n" "\n" "Lower speed usually means less drive noise. However, when using Paranoia error correction modes for increased accuracy, generally much larger speeds are required to prevent buffer underruns (and thus audible drop-outs).\n" "\n" "Please note that these settings do not apply to CD Ripping, which always happens with maximum available speed and with error correction modes manually set before every run." msgstr "" msgid "" "\n" "Most drives let Aqualung know when a CD has been inserted or removed by providing a 'media changed' flag. However, some drives don't set this flag properly, and thus it may happen that a newly inserted CD remains unnoticed to Aqualung. In such cases, enabling this option should help." msgstr "" msgid "" "\n" "Here you should enter a comma-separated list of domains\n" "that should be accessed without using the proxy set above.\n" "Example: localhost, .localdomain, .my.domain.com" msgstr "" "\n" "Här borde du skriva in en kommaseparerad\n" "lista av domäner som bör kunna kommas åt\n" "utan att använda proxyinställningen ovanför.\n" "Exempel: localhost, .localdomain, .my.domain.com" msgid "Title Format" msgstr "Titelformat" msgid "Programmable title format file" msgstr "Programmingsbar titelformatsfil" msgid "Implicit command line" msgstr "" msgid "Miscellaneous" msgstr "Diverse" msgid "Enable tooltips" msgstr "Aktivera verktygstips" msgid "Enable systray" msgstr "Aktivera ikon i systembricka" msgid "Put control buttons at the bottom of playlist" msgstr "Placera kontrollknappar i nederkanten av spellista" msgid "Disable control buttons relief" msgstr "" msgid "Combine play and pause buttons" msgstr "Kombinera knapparna spela och pausa" msgid "Keep main window always on top" msgstr "Låt alltid huvudfönstret vara överst" msgid "Simple view in LADSPA patch builder" msgstr "" msgid "United windows minimization" msgstr "" msgid "Show song name in the main window's title" msgstr "Visa låtnamn i huvudfönstrets titel" msgid "Show hidden files and directories in file choosers" msgstr "" msgid "Show tags tab first in the file info dialog" msgstr "" msgid "Cover art" msgstr "Omslagsbild" msgid "Default cover width:" msgstr "Standardbredd för omslagsbild:" msgid "50 pixels" msgstr "50 bildpunkter" msgid "100 pixels" msgstr "100 bildpunkter" msgid "200 pixels" msgstr "200 bildpunkter" msgid "300 pixels" msgstr "300 bildpunkter" msgid "use browser window width" msgstr "" msgid "Do not magnify images with smaller width" msgstr "Förstora inte bilder med mindre bredd" msgid "Show cover thumbnail for Music Store tracks only" msgstr "Visa bara omslagsbildsikon för musikbiblioteksspår" msgid "Don't show cover thumbnail in the main window" msgstr "Visa inte omslagsbildsikon i huvudfönstret" msgid "Playlist" msgstr "Spellista" msgid "Embed playlist into main window" msgstr "Bädda in spellista i huvudfönstret" msgid "Save and restore the playlist on exit/startup" msgstr "Spara och återställ spellista vid avslutning/uppstart" msgid "Save playlist periodically [min]:" msgstr "Spara spellista periodvis [min]:" msgid "Album mode is the default when adding entire records" msgstr "Albumläge är standard när hela skivor läggs till" msgid "Always show the tab bar" msgstr "Visa alltid flikraden" msgid "Show close button in tab" msgstr "Visa stäng knapp i flik" msgid "When shuffling, records added in Album mode are played in order" msgstr "När funktionen blanda används spelas skivor tilllagda i albumläge i ordning" msgid "Enable statusbar" msgstr "Aktivera statusmätare" msgid "Enable statusbar in playlist" msgstr "Aktivera statusmätare i spellista" msgid "Show soundfile size in statusbar" msgstr "Visa ljudfilstorlek i statusmätaren" msgid "Show RVA values" msgstr "Visa RVA-värden" msgid "Show track lengths" msgstr "Visa spårspeltider" msgid "Show active track name in bold" msgstr "Visa aktivt spårnamn i fetstil" msgid "Enable rules hint" msgstr "" msgid "Playlist column order" msgstr "Kolumnordning för spellista" msgid "" "Drag and drop entries in the list below \n" "to set the column order in the Playlist." msgstr "" "Drag och släpp poster i listan nedanför\n" "för att ställa in kolumnordningen i spellistan." msgid "Column" msgstr "Kolumn" msgid "Track titles" msgstr "Spårtitlar" msgid "RVA values" msgstr "RVA-värden" msgid "Track lengths" msgstr "Spårspeltider" msgid "Hide comment pane" msgstr "Dölj kommentarpanel" msgid "Hide the Music Store comment pane" msgstr "Dölj kommentatorspanelen för musikbibliotek" msgid "Enable toolbar" msgstr "Aktivera verktygsrad" msgid "Enable toolbar in Music Store" msgstr "Aktivera verktygsrad i musikbibliotek" msgid "Enable statusbar in Music Store" msgstr "Aktivera statusmätare i musikbibliotek" msgid "Expand Stores on startup" msgstr "Expandera bibliotek vid uppstart" msgid "Enable tree node icons" msgstr "" msgid "Enable Music Store tree node icons" msgstr "" msgid "Ask for confirmation when removing items" msgstr "Fråga efter bekräftelse när objekt tas bort" msgid "Paths to Music Store databases" msgstr "Sökvägar till musikbiblioteksdatabaser" msgid "Path" msgstr "Sökväg" msgid "Access" msgstr "Åtkomstskydd" msgid "Refresh" msgstr "Uppdatera" msgid "DSP" msgstr "" msgid "LADSPA plugin processing" msgstr "Behandlar LADSPA-insticksmodul" msgid "Pre Fader (before Volume & Balance)" msgstr "" msgid "Post Fader (after Volume & Balance)" msgstr "" msgid "" "Aqualung is compiled without LADSPA plugin support.\n" "See the About box and the documentation for details." msgstr "" "Aqualung är kompilerat utan stöd för LADSPA-insticksmodul.\n" "Se Om-rutan och dokumentationen för fler detaljer." msgid "Sample Rate Converter type" msgstr "Samplingfrekvenskonverterartyp" msgid "" "Aqualung is compiled without Sample Rate Converter support.\n" "See the About box and the documentation for details." msgstr "" "Aqualung är kompilerat utan stöd för samplingsfrekvenskonverterare.\n" "Se Om-rutan och dokumentationen för fler detaljer." msgid "Playback RVA" msgstr "RVA-uppspelning" msgid "Enable playback RVA" msgstr "Aktivera RVA-uppspelning" msgid "Listening environment:" msgstr "" msgid "Audiophile" msgstr "Audiofil" msgid "Living room" msgstr "Vardagsrum" msgid "Office" msgstr "Kontor" msgid "Noisy workshop" msgstr "Bullrig verkstad" msgid "Reference volume [dBFS] :" msgstr "Referensvolym [dBFS] :" msgid "Steepness [dB/dB] :" msgstr "" msgid "RVA for Unmeasured Files [dB] :" msgstr "" msgid "Apply averaged RVA to tracks of the same record" msgstr "Tillämpa genomsnittligt RVA till spår på samma skiva" msgid "Drop statistical aberrations based on" msgstr "" #, no-c-format msgid "% of standard deviation" msgstr "% av standardavvikelse" msgid "Linear threshold [dB]" msgstr "" msgid "Linear threshold [dB] :" msgstr "" #, no-c-format msgid "% of standard deviation :" msgstr "% av standardavvikelse :" msgid "ReplayGain tag to use (with fallback to the other): " msgstr "" msgid "Replaygain_track_gain" msgstr "" msgid "Replaygain_album_gain" msgstr "" msgid "Adding files to Playlist" msgstr "Lägger till filer till spellista" msgid "" "Use basename only instead of full path\n" "if no metadata is available." msgstr "" msgid "Metadata editor (File info dialog)" msgstr "Metadataredigerare (filinformationsdialog)" msgid "" "When adding new frames, try to set their contents\n" "from another tag's equivalent frame." msgstr "" msgid "Batch update & encode (mass tagger, CD ripper, file export)" msgstr "" msgid "Tags to add when creating or updating MPEG audio files:" msgstr "Taggar att lägga till vid skapande eller uppdatering av MPEG-ljudfiler:" msgid "" "Note: pre-existing tags will be updated even though they\n" "might not be checked here." msgstr "" "Beakta: redan existerande taggar kommer att uppdateras\n" "även om de kanske inte är avbockade här." msgid "CD Audio" msgstr "Cd-ljud" msgid "CD drive speed:" msgstr "Cd-romhastighet:" msgid "\tMaximum number of retries:" msgstr "Maximala antalet återförsök:" msgid "Force TOC re-read on every drive scan" msgstr "" msgid "Automatically add CDs to Playlist" msgstr "Lägg automatiskt till cd-skivor till spellista" msgid "Automatically remove CDs from Playlist" msgstr "Ta automatiskt bort cd-skivor från spellista" msgid "CDDB server:" msgstr "CDDB-server:" msgid "Connection timeout [sec]:" msgstr "" msgid "Email address for submission:" msgstr "E-postadress för uppladdning:" msgid "Local CDDB directory:" msgstr "Lokal CDDB-katalog:" msgid "Use the local database only" msgstr "Använd bara den lokala databasen" msgid "Protocol for querying (direct connection only):" msgstr "Frågeprotokoll (bara direktanslutning):" msgid "CDDBP (port 888)" msgstr "CDDBP (port 888)" msgid "HTTP (port 80)" msgstr "HTTP (port 80)" msgid "Internet" msgstr "Internet" msgid "Direct connection to the Internet" msgstr "Direktanslutning till internet" msgid "Connect via HTTP proxy" msgstr "Anslut via HTTP-proxy" msgid "Proxy settings" msgstr "Proxyinställningar" msgid "Proxy host:" msgstr "Proxyvärd:" msgid "Port:" msgstr "Port:" msgid "No proxy for:" msgstr "Ingen proxy för:" msgid "Timeout for socket I/O:" msgstr "" msgid "seconds" msgstr "sekunder" msgid "Appearance" msgstr "Utseende" msgid "Override skin settings" msgstr "Förbigå skalinställningar" msgid "Fonts" msgstr "Typsnitt" msgid "Playlist: " msgstr "Spellista:" msgid "Music Store: " msgstr "Musikbibliotek:" msgid "Big timer: " msgstr "Stort tidur:" msgid "Small timers: " msgstr "Små tidur:" msgid "Song title: " msgstr "Låttitel:" msgid "Song info: " msgstr "Låtinformation:" msgid "Statusbar: " msgstr "Statusmätare:" msgid "Colors" msgstr "Färger" msgid "Song in playlist: " msgstr "Låt i spellista:" msgid "Active song in playlist: " msgstr "Aktiv låt i spellista:" msgid "Error in title format string" msgstr "" msgid "(Untitled)" msgstr "(Namnlös)" #, c-format msgid " (%d/%d)" msgstr " (%d/%d)" msgid "Select files" msgstr "Välj filer" msgid "Select directory" msgstr "Välj katalog" msgid "Add URL" msgstr "Lägg till url" msgid "URL:" msgstr "URL:" msgid "Please specify the file to save the playlist to." msgstr "Var god ange filen som spellistan ska sparas till." msgid "Please specify the file to load the playlist from." msgstr "Var god ange filen som spellistan ska läsas in från." msgid "" "Playback RVA is currently disabled.\n" "Do you want to enable it now?" msgstr "" "RVA-uppspelning är för tillfället inaktiverat.\n" "Vill du aktivera det nu?" msgid "counting..." msgstr "räknar..." msgid "track" msgstr "spår" msgid "tracks" msgstr "spår" msgid "Rename playlist" msgstr "Byt namn på spellista" msgid "Name:" msgstr "Namn:" msgid "New tab" msgstr "Ny flik" msgid "Close tab" msgstr "Stäng flik" msgid "Undo close tab" msgstr "Ångra stäng flik" msgid "Close other tabs" msgstr "Stäng andra flikar" msgid " Selected: " msgstr " Markerade:" msgid "Total: " msgstr "Totalt:" msgid "Add files" msgstr "Lägg till filer" msgid "" "Add files to playlist\n" "(Press right mouse button for menu)" msgstr "" "Lägg till filer till spellista\n" "(Tryck på höger musknapp för meny)" msgid "Select all" msgstr "Markera alla" msgid "" "Select all songs in playlist\n" "(Press right mouse button for menu)" msgstr "" "Markera alla låtar i spellista\n" "(Tryck höger musknapp för meny)" msgid "Remove selected" msgstr "Ta bort markerade" msgid "" "Remove selected songs from playlist\n" "(Press right mouse button for menu)" msgstr "" "Ta bort markerade låtar från spellista\n" "(Tryck höger musknapp för meny)" msgid "Add directory" msgstr "Lägg till katalog" msgid "Select none" msgstr "Markera ingen" msgid "Invert selection" msgstr "" msgid "Remove all" msgstr "Ta bort alla" msgid "Remove dead" msgstr "Ta bort döda" msgid "Cut selected" msgstr "Klipp ut markerade" msgid "Save playlist" msgstr "Spara spellista" msgid "Save all playlists" msgstr "Spara alla spellistor" msgid "Load playlist in new tab" msgstr "Läs in spellista i en ny flik" msgid "Load playlist" msgstr "Läs in spellista" msgid "Enqueue playlist" msgstr "Lägg spellista i kö" msgid "Send to iFP device" msgstr "Skicka till iFP-enhet" msgid "Calculate RVA" msgstr "Beräkna RVA" msgid "Separate" msgstr "Separera" msgid "Average" msgstr "Genomsnitt" msgid "Reread file metadata" msgstr "Läs om filmetadata" msgid "File info..." msgstr "Filinformation..." msgid "Roll to active song" msgstr "Gå till aktiv låt" msgid "Stop adding files" msgstr "Sluta lägg till filer" msgid "Files selected for removal" msgstr "Markerade filer att ta bort" msgid "Remove files" msgstr "Ta bort filer" msgid "" "The selected files will be deleted from the filesystem. No recovery will be possible after this operation.\n" "\n" "Do you want to proceed?" msgstr "" "De markerade filerna kommer att raderas från filsystemet. Det går inte att återställa detta efter denna åtgärd.\n" "\n" "Vill du fortsätta?" #, c-format msgid "Unable to remove %d file." msgstr "Kan inte ta bort %d fil." #, c-format msgid "Unable to remove %d files." msgstr "Kan inte ta bort %d filer." msgid "LADSPA patch builder" msgstr "" msgid "Available plugins" msgstr "Tillgängliga insticksmoduler" msgid "ID" msgstr "" msgid "Category" msgstr "Kategori" msgid "Inputs" msgstr "Indata" msgid "Outputs" msgstr "Utdata" msgid "Running plugins" msgstr "Kör insticksmoduler" msgid "_Configure" msgstr "_Konfigurera" msgid "Enable all plugins" msgstr "Aktivera alla insticksmoduler" msgid "Disable all plugins" msgstr "Inaktivera alla insticksmoduler" msgid "Invert current state" msgstr "" msgid "Clear list" msgstr "Töm lista" msgid "Untitled" msgstr "Namnlös" msgid "JACK Port Setup" msgstr "JACK-portinställning" msgid "Rescan" msgstr "Uppdatera" msgid "Available connections" msgstr "Tillgängliga anslutningar" msgid "Clear connections" msgstr "Töm anslutningar" msgid " out L" msgstr " ut V" msgid " out R" msgstr " ut H" msgid "Search the Music Store" msgstr "Sök i musikbiblioteket" msgid "Key: " msgstr "" msgid "Case sensitive" msgstr "Skiftlägeskänslig" msgid "Exact matches only" msgstr "" msgid "Select first and close window" msgstr "Välj först och stäng fönstret" msgid "Search in:" msgstr "Sök i:" msgid "Artist names" msgstr "Artistnamn" msgid "Record titles" msgstr "Skivtitlar" msgid "Comments" msgstr "Kommentarer" msgid "Search" msgstr "Sök" msgid "Search the Playlist" msgstr "Sök i spellistan" msgid "Available skins" msgstr "Tillgängliga skal" msgid "Drive info" msgstr "Cd-rominformation" msgid "Device path:" msgstr "Enhetssökväg:" msgid "Vendor:" msgstr "Tillverkare:" msgid "Revision:" msgstr "Version:" msgid "" "The information below is reported by the drive, and\n" "may not reflect the actual capabilities of the device." msgstr "" "Informationen nedan anges av cd-romenheten och\n" "kanske inte speglar dess faktiska funktioner." msgid "Eject" msgstr "Mata ut" msgid "Close tray" msgstr "Stäng lucka" msgid "Disable manual eject" msgstr "Inaktivera manuell utmatning" msgid "Select juke-box disc" msgstr "Välj jukebox-disk" msgid "Set drive speed" msgstr "Ställ in cd-romhastighet" msgid "Detect media change" msgstr "Detektera mediabyte" msgid "Read multiple sessions" msgstr "Läs multipla sessioner" msgid "Hard reset device" msgstr "" msgid "Reading" msgstr "Läser" msgid "Play CD Audio" msgstr "Spela cd-ljud" msgid "Read CD-DA" msgstr "Läs cd-da" msgid "Read CD+G" msgstr "Läs cd+g" msgid "Read CD-R" msgstr "Läs cd-r" msgid "Read CD-RW" msgstr "Läs cd-rw" msgid "Read DVD-R" msgstr "Läs dvd-r" msgid "Read DVD+R" msgstr "Läs dvd+r" msgid "Read DVD-RW" msgstr "Läs dvd-rw" msgid "Read DVD+RW" msgstr "Läs dvd+rw" msgid "Read DVD-RAM" msgstr "Läs dvd-ram" msgid "Read DVD-ROM" msgstr "Läs dvd-rom" msgid "C2 Error Correction" msgstr "C2-felkorrigering" msgid "Read Mode 2 Form 1" msgstr "Läs Mode 2 Form 1" msgid "Read Mode 2 Form 2" msgstr "Läs Mode 2 Form 2" msgid "Read MCN" msgstr "Läs MCN" msgid "Read ISRC" msgstr "Läs ISRC" msgid "Writing" msgstr "Skriver" msgid "Write CD-R" msgstr "Skriv cd-r" msgid "Write CD-RW" msgstr "Skriv cd-rw" msgid "Write DVD-R" msgstr "Skriv dvd-r" msgid "Write DVD+R" msgstr "Skriv dvd+r" msgid "Write DVD-RW" msgstr "Skriv dvd-rw" msgid "Write DVD+RW" msgstr "Skriv dvd+rw" msgid "Write DVD-RAM" msgstr "Skriv dvd-ram" msgid "Mount Rainier" msgstr "Mount Rainier" msgid "Burn Proof" msgstr "" msgid "Disc info" msgstr "Diskinformation" msgid "This CD does not contain CD-Text information." msgstr "Denna cd innehåller ingen cd-text-information." msgid "drive" msgstr "cd-rom" msgid "drives" msgstr "cd-romenheter" msgid "record" msgstr "skiva" msgid "records" msgstr "skivor" msgid "Add to playlist" msgstr "Lägg till i spellista" msgid "Add to playlist (Album mode)" msgstr "Lägg till i spellista (albumläge)" msgid "CDDB query for this CD..." msgstr "CDDB-fråga efter denna cd..." msgid "Submit CD to CDDB database..." msgstr "Skicka in cd till CDDB-databasen..." msgid "Rip CD..." msgstr "Extrahera cd..." msgid "Disc info..." msgstr "Diskinformation..." msgid "Drive info..." msgstr "Cd-rominformation..." msgid "Comments:" msgstr "Kommentarer:" msgid "Please select the xml file for this store." msgstr "Var god ange xmlfilen för detta bibliotek." msgid "Create empty store" msgstr "Skapa ett tomt bibliotek" msgid "Visible name:" msgstr "Synligt namn:" msgid "Edit Store" msgstr "Redigera bibliotek" msgid "Use relative paths in store file" msgstr "" msgid "Add Artist" msgstr "Lägg till artist" msgid "Name to sort by:" msgstr "Namn att sortera efter:" msgid "Edit Artist" msgstr "Redigera artist" msgid "Please select the audio files for this record." msgstr "Var god välj ljudfilerna för denna skiva." msgid "Add Record" msgstr "Lägg till skiva" msgid "Auto-create tracks from these files:" msgstr "Skapa automatiskt spår från dessa filer:" msgid "_Add files..." msgstr "_Lägg till filer..." msgid "Edit Record" msgstr "Redigera skiva" msgid "Please select the audio file for this track." msgstr "Var god välj ljudfilen för denna skiva." msgid "Add Track" msgstr "Lägg till spår" msgid "Edit Track" msgstr "Redigera spår" msgid "Duration:" msgstr "Varaktighet:" #, c-format msgid "Unmeasured" msgstr "" msgid "Volume level:" msgstr "Volymnivå:" msgid "Use manual RVA value [dB]" msgstr "Använd manuellt RVA-värde [dB]" #, c-format msgid "Really remove \"%s\" from the Music Store?" msgstr "Vill du verkligen ta bort \"%s\" från musikbiblioteket?" msgid "Stop adding songs" msgstr "Sluta lägg till låtar" #, c-format msgid "" "The store '%s' already exists.\n" "Add it on the Settings/Music Store tab." msgstr "" "Biblioteket '%s' finns redan.\n" "Lägg till det i fliken Inställningar/Musikbibliotek." #, c-format msgid "Really remove store \"%s\" from the Music Store?" msgstr "Vill du verkligen ta bort bibliotek \"%s\" från musikbiblioteket?" msgid "Remove Store" msgstr "Ta bort bibliotek" msgid "Do you want to save the store before removing?" msgstr "Vill du spara biblioteket innan det tas bort?" msgid "Remove Artist" msgstr "Ta bort artist" msgid "Remove Record" msgstr "Ta bort skiva" msgid "Remove Track" msgstr "Ta bort spår" msgid "Update file metadata" msgstr "Uppdatera filmetadata" msgid "Track name" msgstr "Spårnamn" msgid "Track comment" msgstr "Spårkommentar" msgid "Track number" msgstr "Spårnummer" msgid "Failed to set metadata for the following files:" msgstr "Misslyckades med att ställa in metadata för följande filer:" msgid "Filename" msgstr "Filnamn" msgid "Reason" msgstr "Orsak" msgid "(no comment)" msgstr "(ingen kommentar)" msgid "artist" msgstr "artist" msgid "artists" msgstr "artister" msgid "Build / Update store from filesystem..." msgstr "Bygg / uppdatera bibliotek från filsystem..." msgid "Edit store..." msgstr "Redigera bibliotek..." msgid "Export store..." msgstr "Exportera bibliotek..." msgid "Save store" msgstr "Spara bibliotek" msgid "Remove store" msgstr "Ta bort bibliotek" msgid "Add new artist to this store..." msgstr "Lägg till ny artist till detta bibliotek..." msgid "Calculate volume (recursive)" msgstr "Beräkna volym (rekursivt)" msgid "Unmeasured tracks only" msgstr "" msgid "All tracks" msgstr "Alla spår" msgid "Batch-update file metadata..." msgstr "Satsfilsuppdatera filmetadata..." msgid "Add new artist..." msgstr "Lägg till ny artist..." msgid "Edit artist..." msgstr "Redigera artist..." msgid "Export artist..." msgstr "Exportera artist..." msgid "Remove artist" msgstr "Ta bort artist" msgid "Add new record to this artist..." msgstr "Lägg till ny skiva till denna artist..." msgid "Add new record..." msgstr "Lägg till ny skiva..." msgid "Edit record..." msgstr "Redigera skiva..." msgid "Export record..." msgstr "Exportera skiva..." msgid "Remove record" msgstr "Ta bort skiva" msgid "Add new track to this record..." msgstr "Lägg till nytt spår till denna skiva..." msgid "CDDB query for this record..." msgstr "CDDB-fråga efter denna skiva..." msgid "Submit record to CDDB database..." msgstr "Skicka in skiva till CDDB-databasen..." msgid "Add new track..." msgstr "Lägg till nytt spår..." msgid "Edit track..." msgstr "Redigera spår..." msgid "Export track..." msgstr "Exportera spår..." msgid "Remove track" msgstr "Ta bort spår" msgid "Calculate volume" msgstr "Beräkna volym" msgid "Only if unmeasured" msgstr "" msgid "In any case" msgstr "Stora och/eller små bokstäver" msgid "Update file metadata..." msgstr "Uppdatera filmetadata..." msgid "Please select the download directory for this podcast." msgstr "Var god välj hämtningskatalogen för denna poddsändning." msgid "Subscribe to new feed" msgstr "Prenumerera på en ny webbkanal" msgid "Edit feed settings" msgstr "Redigera webbkanalsinställningar" msgid "Podcast URL:" msgstr "Poddsändningurl:" msgid "Download directory:" msgstr "Hämtningskatalog:" msgid "Auto-check interval [hour]:" msgstr "" msgid "" "Automatic update has been disabled for all feeds\n" "in the Podcasts store popup menu." msgstr "" "Automatisk uppdatering har inaktiverats för alla webbkanaler\n" "i poddsändningens bibliotekspopuppmeny." msgid "Limits" msgstr "Begränsningar" msgid "Maximum number of items:" msgstr "Maximalt antal objekt:" msgid "Remove older items [day]:" msgstr "Ta bort äldre objekt [dag]:" msgid "Maximum space to use [MB]:" msgstr "Maximalt utrymme att använda [MB]:" msgid "Podcasts" msgstr "Poddsändningar" msgid "Updating..." msgstr "Uppdaterar..." msgid "Delete downloaded items from the filesystem" msgstr "Radera hämtade objekt från filsystem" msgid "Remove feed" msgstr "Ta bort webbkanal" #, c-format msgid "Really remove '%s' from the Music Store?" msgstr "Vill du verkligen ta bort '%s' från musikbiblioteket?" msgid "Reorder feeds" msgstr "Ordna om webbkanaler" msgid "" "Drag and drop entries in the list\n" "to set the feed order in the Music Store." msgstr "" "Drag och släpp poster i listan\n" "för att ställa in webbkanalsordningen i musikbiblioteket." #, c-format msgid "Downloading %d/%d (%d%%) ..." msgstr "Hämtar %d/%d (%d%%) ..." msgid "item" msgstr "objekt" msgid "items" msgstr "objekt" msgid "new item" msgstr "nytt objekt" msgid "new items" msgstr "nya objekt" msgid "feed" msgstr "webbkanal" msgid "feeds" msgstr "webbkanaler" msgid "Export item..." msgstr "Exportera objekt..." msgid "Add all items to playlist" msgstr "Lägg till alla objekt till spellista" msgid "Add all items to playlist (Album mode)" msgstr "Lägg till alla objekt till spellista (albumläge)" msgid "Add new items to playlist" msgstr "Lägg till nya objekt till spellista" msgid "Add new items to playlist (Album mode)" msgstr "Lägg till nya objekt till spellista (albumläge)" msgid "Edit feed" msgstr "Redigera webbkanal" msgid "Export all items..." msgstr "Exportera alla objekt..." msgid "Export new items..." msgstr "Exportera nya objekt..." msgid "Update feed" msgstr "Uppdatera webbkanal" msgid "Abort ongoing update" msgstr "Avbryt pågående uppdatering" msgid "Update all feeds" msgstr "Uppdatera alla webbkanaler" msgid "Automatically update feeds" msgstr "Uppdatera automatiskt webbkanaler" msgid "Unexpected end of string after '?'." msgstr "" msgid "Expected '}' after '{', but end of string found." msgstr "" #, c-format msgid "Unknown conversion type character found after '%%%%'." msgstr "" msgid "Unknown conversion type character found after '?'." msgstr "" msgid "day" msgstr "dag" msgid "days" msgstr "dagar" msgid "All Files" msgstr "Alla filer" msgid "Extended Title Format Files (*.lua)" msgstr "Utökade titelformatsfiler (*.lua)" msgid "Music Store Files (*.xml)" msgstr "Musikbiblioteksfiler (*.xml)" msgid "Aqualung playlist (*.xml)" msgstr "Aqualung-spellista (*.xml)" msgid "MP3 Playlist (*.m3u)" msgstr "MP3-spellista (*.m3u)" msgid "Multimedia Playlist (*.pls)" msgstr "Multimedia-spellista (*.pls)" msgid "All Playlist Files" msgstr "Alla spellistans filer" msgid "All Audio Files" msgstr "Alla ljudfiler" msgid "Sound Files (*.wav, *.aiff, *.au, ...)" msgstr "Ljudfiler (*.wav, *.aiff, *.au, ...)" msgid "Free Lossless Audio Codec (*.flac)" msgstr "Free Lossless Audio Codec (*.flac)" msgid "MPEG Audio (*.mp3, *.mpa, *.mpega, ...)" msgstr "MPEG Audio (*.mp3, *.mpa, *.mpega, ...)" msgid "Ogg Vorbis (*.ogg)" msgstr "Ogg Vorbis (*.ogg)" msgid "Ogg Speex (*.spx)" msgstr "Ogg Speex (*.spx)" msgid "Musepack (*.mpc)" msgstr "Musepack (*.mpc)" msgid "Monkey's Audio Codec (*.ape)" msgstr "Monkey's Audio Codec (*.ape)" msgid "Modules (*.xm, *.mod, *.it, *.s3m, ...)" msgstr "Moduler (*.xm, *.mod, *.it, *.s3m, ...)" msgid "Compressed modules (*.gz, *.bz2)" msgstr "Komprimerade moduler (*.gz, *.bz2)" msgid "Compressed modules (*.gz)" msgstr "Komprimerade moduler (*.gz)" msgid "Compressed modules (*.bz2)" msgstr "Komprimerade moduler (*.bz2)" msgid "WavPack (*.wv)" msgstr "WavPack (*.wv)" msgid "LAVC audio/video files" msgstr "" msgid "Resume" msgstr "Återuppta" msgid "Calculating volume level" msgstr "Beräknar volymnivå" msgid "Profile: Telephone" msgstr "Profil: Telefon" msgid "Profile: Thumb" msgstr "" msgid "Profile: Radio" msgstr "Profil: Radio" msgid "Profile: Standard" msgstr "Profil: Standard" msgid "Profile: Xtreme" msgstr "Profil: Extrem" msgid "Profile: Insane" msgstr "Profil: Galen" msgid "Profile: Braindead" msgstr "Profil: Hjärndöd" msgid "Layer I" msgstr "Layer I" msgid "Layer II" msgstr "Layer II" msgid "Layer III" msgstr "Layer III" msgid "Unrecognized" msgstr "" msgid "Single channel" msgstr "En kanal" msgid "Dual channel" msgstr "Dubbla kanaler" msgid "Joint stereo" msgstr "Joint stereo" msgid "Stereo" msgstr "Stereo" msgid "Emphasis: none" msgstr "" msgid "Emphasis:" msgstr "" msgid "Emphasis: reserved" msgstr "" msgid "bit signed" msgstr "" msgid "bit unsigned" msgstr "" msgid "bit float" msgstr "" msgid "bit double" msgstr "" msgid "encoding" msgstr "kodning" msgid "Compression: Fast" msgstr "Komprimering: Snabb" msgid "Compression: Normal" msgstr "Komprimering: Normal" msgid "Compression: High" msgstr "Komprimering: Hård" msgid "Compression: Extra High" msgstr "Komprimering: Extra hård" msgid "Compression: Insane" msgstr "Komprimering: Galet" aqualung-0.9beta11/src/po/uk.po0000644000175000001440000027756611331334210013314 00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Tom Szilagyi # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # # msgid "" msgstr "" "Project-Id-Version: aqualung 0.9beta10\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2010-01-17 16:11+0200\n" "PO-Revision-Date: 2010-01-17 16:14+0300\n" "Last-Translator: Vladimir Smolyar \n" "Language-Team: Ukrainian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" msgid "About" msgstr "Про програму" msgid "Build version: " msgstr "Версія збірки: " msgid "Homepage:" msgstr "Домашня сторінка:" msgid "Authors:" msgstr "Автори:" msgid "Core design, engineering & programming:\n" msgstr "Головний дизайн, розробка та програмування:\n" msgid "Skin support, look & feel, GUI hacks:\n" msgstr "Підтримка жупанів, вигляд та поведінка, програмування ГІК:\n" msgid "Programming, GUI engineering:\n" msgstr "Програмування, розробка ГІК:\n" msgid "OpenBSD compatibility, metadata tweaks:\n" msgstr "Сумісність з OpenBSD, трюки з метаданими:\n" msgid "Translators:" msgstr "Перекладачі:" msgid "French:\n" msgstr "Французька:\n" msgid "German:\n" msgstr "Німецька:\n" msgid "Hungarian:\n" msgstr "Угорська:\n" msgid "Italian:\n" msgstr "Італійська:\n" msgid "Japanese:\n" msgstr "Японська:\n" msgid "Russian:\n" msgstr "Російська:\n" msgid "Swedish:\n" msgstr "Шведська:\n" msgid "Ukrainian:\n" msgstr "Українська:\n" msgid "Graphics:" msgstr "Графіка:" msgid "Logo, icons:\n" msgstr "Логотип, іконки:\n" msgid "This Aqualung binary is compiled with:" msgstr "Цей файл Aqualung скомпільовано з:" msgid "Optional features:" msgstr "Додаткові можливості:" msgid "LADSPA plugin support\n" msgstr "Підтримка розширень LADSPA\n" msgid "CDDA (Audio CD) support\n" msgstr "Підтримка CDDA (Аудіо CD)\n" msgid "CDDB support\n" msgstr "Підтримка CDDB\n" msgid "Sample Rate Converter support\n" msgstr "Підтримка конвертера частоти дискретизації\n" msgid "iRiver iFP driver support\n" msgstr "Підтримка драйвера iRiver iFP\n" msgid "Loop playback support\n" msgstr "Підтримка зацикленого відтворення\n" msgid "Systray support\n" msgstr "Підтримка системного лотка\n" msgid "Podcast support\n" msgstr "Підтримка подкастів\n" msgid "Lua (programmable title formatting) support\n" msgstr "Підтримка Lua (програмоване форматування заголовка)\n" msgid "Decoding support:" msgstr "Підтримка декодування:" msgid "sndfile (WAV, AIFF, etc.)\n" msgstr "Звукові файли (WAV, AIFF, etc.)\n" msgid "Free Lossless Audio Codec (FLAC)\n" msgstr "Free Lossless Audio Codec (FLAC)\n" msgid "Ogg Vorbis\n" msgstr "Ogg Vorbis\n" msgid "Ogg Speex\n" msgstr "Ogg Speex\n" msgid "MPEG Audio (MPEG 1-2.5 Layer I-III)\n" msgstr "MPEG Audio (MPEG 1-2.5 Layer I-III)\n" msgid "MOD Audio (MOD, S3M, XM, IT, etc.)\n" msgstr "MOD Audio (MOD, S3M, XM, IT, etc.)\n" msgid "Musepack\n" msgstr "Musepack\n" msgid "Monkey's Audio Codec\n" msgstr "Monkey's Audio Codec\n" msgid "WavPack\n" msgstr "WavPack\n" msgid "LAVC (AC3, AAC, WavPack, WMA, etc.)\n" msgstr "LAVC (AC3, AAC, WavPack, WMA, etc.)\n" msgid "Encoding support:" msgstr "Підтримка кодування:" msgid "sndfile (WAV)\n" msgstr "Звукові файли (WAV)\n" msgid "LAME (MP3)\n" msgstr "LAME (MP3)\n" msgid "Output driver support:" msgstr "Підтримка драйверів виводу:" msgid "sndio Audio\n" msgstr "sndio Audio\n" msgid "OSS Audio\n" msgstr "OSS Audio\n" msgid "ALSA Audio\n" msgstr "ALSA Audio\n" msgid "JACK Audio Server\n" msgstr "Аудіо сервер JACK\n" msgid "PulseAudio\n" msgstr "PulseAudio\n" msgid "Win32 Sound API\n" msgstr "Win32 Sound API\n" msgid "" "This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.\n" "\n" "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.\n" "\n" "You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." msgstr "" "Ця програма є вільним програмним забезпеченням; ви можете поширювати його та/або змінювати на умовах Універсальної громадської ліцензії GNU у тому вигляді, у якому її було опубліковано Фондом вільного програмного забезпечення; як версії 2, так і (за вашим розсудом) будь-якої більш пізньої версії.\n" "\n" "Ця програма поширюється у надії, що вона буде корисною, але БЕЗ ЖОДНОЇ ГАРАНТІЇ; навіть без обов'язкової гарантії ТОВАРНОЇ ПРИДАТНОСТІ або ПРИДАТНОСТІ ДО ПЕВНОГО ПРИЗНАЧЕННЯ. Для більш детальної інформації див. Універсальну громадську ліцензію GNU.\n" "\n" "Ви мали отримати копію Універсальної громадської ліцензії GNU разом з цією програмою; якщо ні, то напишіть у Фонд вільного програмного забезпечення: Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." msgid "Enabled" msgstr "Дозволений" msgid "Source" msgstr "Джерело" msgid "CDDB" msgstr "CDDB" msgid "CDDB (not available)" msgstr "CDDB (недосяжний)" msgid "Metadata" msgstr "Метадані" msgid "Filesystem" msgstr "Файлова система" msgid "Capitalization" msgstr "Перетворення до заголовних літер" msgid "Capitalize: " msgstr "Перетворити на заголовні:" msgid "All words" msgstr "Усі слова" msgid "First word only" msgstr "Тільки перше слово" msgid "Force case: " msgstr "Примусово:" msgid "Force other letters to lowercase" msgstr "Перетворити інши літери до нижнього рогістру" msgid "Regular expression" msgstr "Регулярний вираз" msgid "Regexp:" msgstr "РегВир:" msgid "Replace:" msgstr "Заміна:" msgid "Predefined transformations" msgstr "Передвстановлені перетворення" msgid "Remove file extension" msgstr "Прибрати розширення файлу" msgid "Remove leading number" msgstr "Прибрати число на початку" msgid "Convert underscore to space" msgstr "Перетворити підкреслювання на пробіл" msgid "Trim leading, tailing and duplicate spaces" msgstr "Обрізати пробіли на початку, в кінці та ті, що повторюються" msgid "Regexp matches empty string" msgstr "Регулярний вираз співпадає із порожньою строкою" msgid "Please select the root directory." msgstr "Будь ласка, оберіть кореневий каталог." msgid "Select build type" msgstr "Оберіть тим збірка" msgid "Directory driven" msgstr "Відповідно до каталогів" msgid "" "Follows the directory structure to identify the artists and\n" "records. The files are added on a record basis." msgstr "" "Слідує структурою каталогів для визначення виконавців та\n" "записів. Файли додаються на основі записів." msgid "Independent" msgstr "Незалежний" msgid "" "Recursive search from the root directory for audio files.\n" "The files are processed independently, so only metadata\n" "and filename transformation are available." msgstr "" "Рекурсивний пошук аудіофайлів, починаючи із кореневого каталога.\n" "Файли обробляються незалежно, так що доступні тільки\n" "метадані та перетворення імен файлів." msgid "Load settings from Music Store file" msgstr "Завантажити налаштування з файлу Музичного Сховища" msgid "Build/Update store" msgstr "Побудувати/Оновити сховище" msgid "General" msgstr "Головне" msgid "Directory structure" msgstr "Структура каталогів" msgid "Root path:" msgstr "Кореневий шлях:" msgid "_Browse..." msgstr "_Оглянути..." msgid "Structure:" msgstr "Структура:" msgid "root / record / track" msgstr "корінь / запис / доріжка" msgid "root / artist / record / track" msgstr "корінь / виконавець / запис / доріжка" msgid "root / artist / artist / record / track" msgstr "корінь / виконавець / виконавець / запис / доріжка" msgid "root / artist / artist / artist / record / track" msgstr "корінь / виконавець / виконавець / виконавець / запис / доріжка" msgid "Exclude files matching wildcard" msgstr "Виключити файли, що задовільняють маску" msgid "Include only files matching wildcard" msgstr "Включити тільки файли, що задовільняють маску" msgid "Reread data for existing tracks" msgstr "Перечитати дані для існуючих доріжок" msgid "Remove non-existing files from store" msgstr "Видалити неіснуючі файли зі сховища" msgid "Artist" msgstr "Виконавець" msgid "Sort artists by" msgstr "Сортувати виконавців за" msgid "Artist name" msgstr "Ім'ям виконавця" msgid "Artist name (lowercase)" msgstr "Ім'ям виконавця (нижній регістр)" msgid "Directory name" msgstr "Назвою каталога" msgid "Directory name (lowercase)" msgstr "Назвою каталога (нижній регістр)" msgid "Record" msgstr "Запис" msgid "Sort records by" msgstr "Сортувати записи за" msgid "Record name" msgstr "Назвою запису" msgid "Record name (lowercase)" msgstr "Назвою запису (нижній регістр)" msgid "Year" msgstr "Роком" msgid "Add year to the comments of new records" msgstr "Додати рік до коментарів нових записів" msgid "Track" msgstr "Доріжка" msgid "Import Replaygain tag as manual RVA" msgstr "Імпортувати тег Replaygain як ручне налаштування RVA" msgid "Import Comment tag" msgstr "Імпортувати тег коментаря" msgid "Sandbox" msgstr "Пісочниця" msgid "Filename:" msgstr "Назва файлу:" msgid "Test" msgstr "Тест" msgid "Building store from filesystem" msgstr "Побудова сховища з файлової системи" msgid "Processing:" msgstr "Прогрес:" msgid "Action:" msgstr "Дія:" msgid "Abort" msgstr "Перервати" msgid "Unknown Artist" msgstr "Невідомий виконавець" msgid "Unknown Record" msgstr "Невідомий запис" msgid "Scanning files" msgstr "Сканування файлів" msgid "Processing metadata" msgstr "Обробка метаданих" msgid "CDDB lookup" msgstr "Пошук у CDDB" msgid "Name transformation" msgstr "Перетворення імені" msgid "Reading file" msgstr "Читання файлу" msgid "Removing non-existing files" msgstr "Видалення неіснуючих файлів" msgid "Unknown disc" msgstr "Невідомий диск" msgid "No disc" msgstr "Немає диска" msgid "CDDB query" msgstr "Запит у CDDB" msgid "Retrieving matches from server..." msgstr "Отримання збігів з сервера..." msgid "Connecting to CDDB server..." msgstr "Під'єднання до сервера CDDB..." msgid "Error" msgstr "Помилка" msgid "An error occurred while attempting to connect to the CDDB server." msgstr "Під час спроби під'єднання до сервера CDDB виникла помилка." msgid "Warning" msgstr "Попередження" msgid "No matching record found." msgstr "Схожих записів не знайдено." msgid "Import as Sort Key" msgstr "Імпортувати як ключ для сортування" msgid "Import as Title" msgstr "Імпортувати як Назву" msgid "Import as Year" msgstr "Імпортувати як Рік" msgid "" "Artist appears to be in all lowercase.\n" "Do you want to proceed?" msgstr "" "Ім'я виконавця цілком у нижньому регістрі.\n" "Бажаєте продовжити?" msgid "" "Artist appears to be in all uppercase.\n" "Do you want to proceed?" msgstr "" "Ім'я виконавця цілком у верхньому регістрі.\n" "Бажаєте продовжити?" msgid "" "Title appears to be in all lowercase.\n" "Do you want to proceed?" msgstr "" "Назва цілком у нижньому регістрі.\n" "Бажаєте продовжити?" msgid "" "Title appears to be in all uppercase.\n" "Do you want to proceed?" msgstr "" "Назва цілком у верхньому регістрі.\n" "Бажаєте продовжити?" msgid "" "It is very likely that the year is wrong.\n" "Do you want to proceed?" msgstr "" "Схоже, рік вказано невірно.\n" "Бажаєте продовжити?" msgid "The email address provided for submission is invalid." msgstr "Адреса електронної пошти, вказана для підписки, недійсна." msgid "An error occurred while submitting the record to the CDDB server." msgstr "Під час надсилання запису до сервера CDDB виникла помилка." msgid "Correct existing record" msgstr "Виправити існуючий запис" msgid "Submit new record" msgstr "Надіслати новий запис" msgid "Matches:" msgstr "Збіги:" msgid "Artist:" msgstr "Виконавець:" msgid "Title:" msgstr "Назва:" msgid "Year:" msgstr "Рік:" msgid "Category:" msgstr "Категорія:" msgid "(choose a category)" msgstr "(оберіть категорію)" msgid "Genre:" msgstr "Жанр:" msgid "Extended data:" msgstr "Додаткові дані:" msgid "Import as Artist" msgstr "Імпортувати як Виконавця" msgid "Add to Comments" msgstr "Додати до коментарів" msgid "Tracks" msgstr "Доріжки" msgid "You have to provide an email address for CDDB submission." msgstr "Ви маєте вказати адресу електроної пошти для надсилання до CDDB." msgid "Please select the directory for ripped files." msgstr "Будь ласка оберіть каталог для добутих файлів." msgid "(none)" msgstr "(немає)" msgid "fast" msgstr "швидко" msgid "best" msgstr "найкращий" msgid "Compression level:" msgstr "Рівень стискання: Нормальний" msgid "Bitrate [kbps]:" msgstr "Бітрейт [kbps]:" msgid "Artist/Album already existing, not empty" msgstr "Виконавець/Альбом вже існують та непорожні" msgid "" "\n" "The Music Store you selected has a matching Artist and Album, already containing some tracks. If you press OK, these tracks will be removed. The files themselves will be left intact, but they will be removed from the destination Music Store. Press Cancel to get back to change the Artist/Album or the destination Music Store." msgstr "" "\n" "В обраному вами Музичному Сховищі вже є виконавець та альбом, що містить доріжки. Якщо ви натиснете Если вы нажмете ОК, ці треки буде видалено. Файли самі по собі будуть залишені непошкодженими, але вони будуть видалені з даного Музичного Сховища. Нажмите Відміна для повернення до зміни виконавця/альбома або выбору іншого Музичного Сховища." msgid "Rip CD" msgstr "Дістати музику з CD" msgid "Album:" msgstr "Альбом:" msgid "Rip" msgstr "Дістати музику" msgid "No." msgstr "№" msgid "Title" msgstr "Назва" msgid "Select" msgstr "Вибрати" msgid "All" msgstr "Усе" msgid "None" msgstr "Немає" msgid "Output" msgstr "Вихід" msgid "Destination" msgstr "Призначення" msgid "Target directory for ripped files" msgstr "Каталог призначення для добутих файлів." msgid "Add to Music Store" msgstr "Додати до Музичного Сховища" msgid "Format" msgstr "Формат" msgid "File format:" msgstr "Формат файлу:" msgid "VBR encoding" msgstr "Кодування зі змінним потоком" msgid "Tag files with metadata" msgstr "Увести метадані у файли" msgid "Paranoia" msgstr "Paranoia" msgid "Paranoia error correction" msgstr "Корекція помилок Paranoia" msgid "Perform overlapped reads" msgstr "Виконувати читання із перекриванням" msgid "Verify data integrity" msgstr "Перевірити цілісність даних" msgid "Unlimited retry on failed reads (never skip)" msgstr "Необмежена кількість спроб за помилок читання (ніколи не пропускати)" msgid "Maximum number of retries:" msgstr "Максимальна кількість спроб:" msgid "" "\n" "Destination directory is not read-write accessible!" msgstr "" "\n" "Вказаний каталог не доступний для читання/запису!" msgid "Total" msgstr "Разом" msgid "(audio only)" msgstr "(тільки аудіо)" msgid "Ripping CD tracks" msgstr "Діставання доріжок з CD" msgid "Begin" msgstr "Початок" msgid "Length" msgstr "Тривалість" msgid "Progress" msgstr "Прогрес" msgid "Close window when complete" msgstr "Закрити вікно після завершення" msgid "Close" msgstr "Закрити" msgid "Unknown Album" msgstr "Невідомий Альбом" msgid "Unknown Track" msgstr "Невідома Доріжка" msgid "Please select the directory for exported files." msgstr "Будь ласка, оберіть каталог для експортованих файлів." msgid "Copy" msgstr "Копіювати" msgid "Help" msgstr "Допомога" #, c-format msgid "" "\n" "The template string you enter here will be used to construct the filename of the exported files. The Artist, Record and Track names are denoted by %%%%a, %%%%r and %%%%t. The track number and format-dependent file extension are denoted by %%%%n and %%%%x, respectively. The flag %%%%i gives an identifier which is unique within an export session." msgstr "" "\n" "Рядки шаблону, що ви впишете сюди, буде використано для складання ім'я експортованих файлів. Ім'я Виконавця, Запису та Доріжки позначаються %%%%a, %%%%r та %%%%t. Номер доріжки та розширення файлу, що залежить віз формату, позначаються %%%%n та %%%%x, відповідно. Прапор %%%%i дає ідентифікатор, унікальний у межах сеансу експорту." msgid "Export files" msgstr "Експорт файлів" msgid "Location and filename" msgstr "Месце розташування та ім'я файлу" msgid "Target directory:" msgstr "Каталог призначення:" msgid "Create subdirectories for artists" msgstr "Створити підкаталоги для виконавців" msgid "Create subdirectories for albums" msgstr "Створити підкаталоги для альбомів" msgid "" "Subdirectory name\n" "length limit:" msgstr "" "Максимальна довжина\n" "імені підкаталога:" msgid "Filename template:" msgstr "Шаблон імені файлу:" msgid "Filter" msgstr "Фільтр" msgid "Do not reencode files already being in the target format" msgstr "Не перекодувати файли, що вже у форматі призначення" msgid "" "Do not reencode files\n" "matching wildcard:" msgstr "" "Не перекодувати файли,\n" "що задовільняють маску:" msgid "Error in format string" msgstr "Помилка у рядку формату" msgid "Exporting files" msgstr "Експорт файлів" msgid "Source file:" msgstr "Вихідний файл:" msgid "Target file:" msgstr "Файл призначення:" msgid "Progress:" msgstr "Прогрес:" msgid "*File info" msgstr "*Інформація про файл" msgid "File info" msgstr "Інформація про файл" msgid "There are unsaved changes to the file metadata." msgstr "Є незбережені зміни у метаданих файлу." msgid "Save and close" msgstr "Зберегти та закрити" msgid "Discard changes" msgstr "Скасувати зміни" msgid "Do not close" msgstr "Не закривати" #, c-format msgid "" "Conversion error in field %s:\n" "'%s' does not conform to format '%s'!" msgstr "" "Помилка перетворення у полі %s:\n" "'%s' не відповідає формату '%s'!" msgid "" "Attached Picture frame with no image set!\n" "Please set an image or remove the frame." msgstr "" "Прикріплена картинка без зображення!\n" "Будь ласка, встановіть зображення або видаліть картинку." #, c-format msgid "" "Failed to write metadata to file.\n" "Reason: %s" msgstr "" "Неможливо записати метадані до файлу.\n" "Причина: %s" #, c-format msgid "" "Error converting field %s to Year:\n" "'%s' is not an integer number!" msgstr "" "Помилка перетворення поля %s на Рік:\n" "'%s' не є цілим числом!" msgid "Please specify the file to save the image to." msgstr "Будь аска, вкажіть файл для збереження зображення." msgid "(no image)" msgstr "(немає зображення)" msgid "(error loading image)" msgstr "(помилка завантаження зображення)" msgid "Please specify the file to load the image from." msgstr "Будь ласка, вкажіть файл, з якого буде завантажено зображення." #, c-format msgid "" "Could not load image from:\n" "%s" msgstr "" "Неможливо завантажити зображення з:\n" "%s" #, c-format msgid "MIME type: %s" msgstr "Тип MIME: %s" msgid "Picture type:" msgstr "Тип зображення:" msgid "Description:" msgstr "Опис:" msgid "(no description)" msgstr "(немає опису)" msgid "Change" msgstr "Змінити" msgid "Save" msgstr "Зберегти" msgid "Import as Record" msgstr "Імпортувати як Запис" msgid "Import as Track No." msgstr "Імпортувати як № доріжки" msgid "Import as RVA" msgstr "Імпортувати як рівень RVA" msgid "Add" msgstr "Додати" msgid "field:" msgstr "поле:" msgid "tag:" msgstr "тег:" msgid "Audio CD" msgstr "Аудіо CD" msgid "Track:" msgstr "Доріжка:" msgid "File:" msgstr "Файл:" msgid "Audio data" msgstr "Аудіо дані" msgid "Format:" msgstr "Формат:" msgid "Length:" msgstr "Довжина:" msgid "Samplerate:" msgstr "Частота дискретизації:" #, c-format msgid "%ld Hz" msgstr "%ld Гц" msgid "Channel count:" msgstr "Кількість каналів:" msgid "MONO" msgstr "МОНО" msgid "STEREO" msgstr "СТЕРЕО" msgid "Bandwidth:" msgstr "Потік:" msgid "Total samples:" msgstr "Всього семплів:" msgid "Mode:" msgstr "Режим:" msgid "Type:" msgstr "Тип: " msgid "Channels:" msgstr "Канали:" msgid "Patterns:" msgstr "Патернів:" msgid "Samples:" msgstr "Фрагментів:" msgid "Instruments:" msgstr "Інструменти:" msgid "Samples" msgstr "Фрагменти" msgid "Instruments" msgstr "Інструменти" msgid "Name" msgstr "Ім'я" msgid "STOPPING" msgstr "ЗУПИНКА" msgid "Output:" msgstr "Вихід:" msgid "No output" msgstr "Немає виводу" msgid "SRC Type: " msgstr "Тип SRC: " #, c-format msgid "Loop range: %d-%d%% [%s - %s]" msgstr "Діапазон повтору: %d-%d%% [%s - %s]" #, c-format msgid "Loop range: %d-%d%%" msgstr "Діапазон повтору: %d-%d%%" msgid "" "One or more stores in Music Store have been modified.\n" "Do you want to save them before exiting?" msgstr "" "Одне або більше совище в Музичному Сховищі було змінено.\n" "Бажаєте зберегти їя перед виходом?" msgid "Do not exit" msgstr "Не виходити" msgid "Quit" msgstr "Вихід" #, c-format msgid "Position: %d%%" msgstr "Позиція: %d%%" #, c-format msgid "Mute" msgstr "Приглушити" #, c-format msgid "%d dB" msgstr "%d Дб" #, c-format msgid "Volume: %s" msgstr "Гучність: %s" #, c-format msgid "%d%% R" msgstr "%d%% П" #, c-format msgid "%d%% L" msgstr "%d%% Л" #, c-format msgid "C" msgstr "Ц" #, c-format msgid "Balance: %s" msgstr "Баланс: %s" msgid "JACK connection lost" msgstr "З'єднання з JACK втрачено" msgid "JACK has either been shutdown or it disconnected Aqualung because it was not fast enough. All you can do now is restart both JACK and Aqualung." msgstr "JACK було вимкнено, або він від'єднав Aqualung, бо той був недостатньо швидкий. Все, що ви можете тепер зробити, це перезапустити обидва JACK та Aqualung." msgid "Warn me if the Window Manager does not support system tray" msgstr "Попередити мне, якщо менеджер вікон не підтримує системний лоток" msgid "Aqualung is compiled with system tray support, but the status icon could not be embedded in the notification area. Your desktop may not have support for a system tray, or it has not been configured correctly." msgstr "Aqualung скомпільовано з підтримкою системного лотка, але статусна іконка не може бути вбудована у область повідомлень. Можливо, ваш робочий стіл не підтримує системний лоток, або невірно налаштований." msgid "Settings" msgstr "Налаштування" msgid "Skin chooser" msgstr "Вибір жупанів" msgid "JACK port setup" msgstr "Налаштування порту JACK" msgid "Previous song" msgstr "Попередня пісня" msgid "Stop" msgstr "Стоп" msgid "Next song" msgstr "Наступна пісня" msgid "Play/Pause" msgstr "Грати/Пауза" msgid "Play" msgstr "Грати" msgid "Pause" msgstr "Пауза" msgid "Repeat current song" msgstr "Повторювати поточну пісню" msgid "Repeat all songs" msgstr "Повторювати всі пісні" msgid "Shuffle songs" msgstr "Перемішати пісні" msgid "Toggle playlist" msgstr "Вимикач списку програвання" msgid "Toggle music store" msgstr "Вимикач Музичного Сховища" msgid "Toggle LADSPA patch builder" msgstr "Вимикач будівельника патчів LADSPA" msgid "Show Aqualung" msgstr "Показати Aqualung" msgid "Hide Aqualung" msgstr "Сховати Aqualung" msgid "Previous" msgstr "Попередня пісня" msgid "Next" msgstr "Наступна пісня" #, c-format msgid "%.1f MB / %.1f MB" msgstr "%.1f МБ / %.1f МБ" #, c-format msgid "%d / %d files" msgstr "%d / %d файлів" #, c-format msgid "%d / %d directories" msgstr "%d / %d каталогів" msgid "Cannot write to selected directory. Please select another directory." msgstr "Неможливо записани до обраного каталога. Будь ласка, оберіть інший каталог." msgid "Done" msgstr "Зроблено" msgid "Aborted..." msgstr "Скасовано..." msgid "Please enter directory name." msgstr "Уведіть, будь ласка, назву каталога." msgid "Create directory" msgstr "Створити каталог" msgid "Please enter a new name." msgstr "Уведіть, будь ласка, нове ім'я." msgid "Rename" msgstr "Перейменувати" #, c-format msgid "" "Directory '%s' will be removed with its entire contents.\n" "\n" "Do you want to proceed?" msgstr "" "Кталог '%s' буде видалено разом із усім вмістом.\n" "Бажаєте продовжити?" #, c-format msgid "" "File '%s' will be removed.\n" "\n" "Do you want to proceed?" msgstr "" "Файл '%s' буде видалено.\n" "\n" "Бажаєте продовжити?" msgid "Remove" msgstr "Видалити" #, c-format msgid " (%.1f MB)" msgstr " (%.1f МБ)" #, c-format msgid " (capacity = %.1f MB)" msgstr " (місткість = %.1f МБ)" #, c-format msgid " Free space (%.1f MB)" msgstr " ВІльне місце (%.1f МБ)" msgid "" "No suitable iRiver iFP device found.\n" "Perhaps it is unplugged or turned off." msgstr "" "Придатного пристрою iRiver iFP не знайдено.\n" "Можливо, він від'єднаний або вимкнений." msgid "" "Device is busy.\n" "(Aqualung was unable to claim its interface.)" msgstr "" "Пристрій зайнятий.\n" "(Aqualung не зміг встановити свій інтерфейс.)" msgid "" "Device is not responding.\n" "Try jiggling the handle." msgstr "" "Пристрій не відповідає.\n" "Спробуйте поворушити руків'ям." msgid "Please select a local path." msgstr "Будь ласка, оберіть локальний шлях." msgid "Please select at least one valid song from playlist." msgstr "Будь ласка, оберіть хоча б одну дійсну пісню зі списку програвання." #, c-format msgid "" "One song has format unsupported by your player.\n" "\n" "Do you want to proceed?" msgstr "" "Одна з пісень має формат, що не підтримується вашим плеєром.\n" "\n" "Бажаєте продовжити?" #, c-format msgid "" "%d of %d songs have format unsupported by your player.\n" "\n" "Do you want to proceed?" msgstr "" "%d з %d пісень мають формат, що не підтримується вашиим плеєром.\n" "\n" "Бажаєте продовжити?" #, c-format msgid "" "The selected song has format unsupported by your player.\n" "\n" "Do you want to proceed?" msgstr "" "Обрана пісня має формат, що не підтримується вашим плеєром.\n" "\n" "Бажаєте продовжити?" #, c-format msgid "" "None of the selected songs has format supported by your player.\n" "\n" "Do you want to proceed?" msgstr "" "Жодна з обраних пісень не має формату, що підтримується вашим плеєром.\n" "\n" "Бажаєте продовжити?" msgid "iFP device manager (upload mode)" msgstr "Менеджер пристрою iFP (режим відвантаження)" msgid "iFP device manager (download mode)" msgstr "Менеджер пристрою iFP (режим завантаження)" msgid "Selected files:" msgstr "Обрані файли:" msgid "Songs info" msgstr "Інформація про пісні" msgid "Model:" msgstr "Модель:" msgid "Battery" msgstr "Батарея" msgid "Free space" msgstr "Вільне місце" msgid "Device status" msgstr "Стан пристрою" msgid "Size" msgstr "Розмір" msgid "Create a new directory" msgstr "Створити новий каталог" msgid "Remote directory" msgstr "Віддалений каталог" msgid "Local directory" msgstr "Локальний каталог" msgid "Browse" msgstr "Оглянути" msgid "File name: " msgstr "Назва файлу:" msgid "Current file: " msgstr "Поточний файл:" msgid "Overall: " msgstr "Разом:" msgid "Idle" msgstr "Бездіяння" msgid "Transfer progress" msgstr "Прогрес передачі" msgid "Close window when transfer complete" msgstr "Закрити вікно після завершення передачі" msgid "_Upload" msgstr "_Відвантажити" msgid "_Download" msgstr "_Завантажити" msgid "_Abort" msgstr "_Перервати" msgid "Success" msgstr "Успішно" msgid "Memory allocation error" msgstr "Помилка виділення пам'яті" msgid "Unable to open file" msgstr "Неможливо відкрити файл" msgid "No metadata support for this format" msgstr "Немає підтримки метаданих для цього формату" msgid "File is not writable" msgstr "Файл не доступний на запис" msgid "Invalid 'Track no.' field value" msgstr "Невірне значення поля 'Номер трека'" msgid "Invalid 'Genre' field value" msgstr "Невірне значення поля 'Жанр'" msgid "Conversion to target charset failed" msgstr "Перетворення до цільового кодування не вдалося" msgid "Internal error" msgstr "Внутрішня помилка" msgid "Unknown error" msgstr "Невідома помилка" msgid "Album" msgstr "Альбом" msgid "Date" msgstr "Дата" msgid "Genre" msgstr "Жанр" msgid "Track No." msgstr "Номер доріжки" msgid "Comment" msgstr "Коментар" msgid "Disc" msgstr "Диск" msgid "Performer" msgstr "Виконавець" msgid "Description" msgstr "Опис" msgid "Organization" msgstr "Організація" msgid "Location" msgstr "Розташування" msgid "Contact" msgstr "Контактна інформація" msgid "License" msgstr "Ліцензія" msgid "Copyright" msgstr "Авторське право" msgid "ISRC" msgstr "ISRC" msgid "Version" msgstr "Версія" msgid "Subtitle" msgstr "Підзаголовок" msgid "Debut Album" msgstr "Дебютний альбом" msgid "Publisher" msgstr "Видавник" msgid "Conductor" msgstr "Диригент" msgid "Composer" msgstr "Композитор" msgid "Publication Right" msgstr "Права на публікацію" msgid "File" msgstr "Файл" msgid "EAN/UPC" msgstr "EAN/UPC" msgid "ISBN" msgstr "ISBN" msgid "Catalog Number" msgstr "Номер каталога" msgid "Label Code" msgstr "Кол лейбла" msgid "Record Date" msgstr "Дата запису" msgid "Record Location" msgstr "Місце запису" msgid "Media" msgstr "Носій" msgid "Index" msgstr "Зміст" msgid "Related" msgstr "Пов'язана інформація" msgid "Abstract" msgstr "Опис" msgid "Language" msgstr "Мова" msgid "Bibliography" msgstr "Бібліографія" msgid "Introplay" msgstr "Вступ" msgid "BPM" msgstr "BPM" msgid "Encoding Time" msgstr "Час кодування" msgid "Playlist Delay" msgstr "Затримка списку програвання" msgid "Original Release Time" msgstr "Час випуску оригінала" msgid "Release Time" msgstr "Дата випуску" msgid "Tagging Time" msgstr "Час внесення тега" msgid "Encoded by" msgstr "Закодовано" msgid "Lyricist/Text Writer" msgstr "Поет/автор тексту" msgid "File Type" msgstr "Тип файлу" msgid "Involved People" msgstr "Учасники" msgid "Content Group" msgstr "Тип вмісту" msgid "Initial key" msgstr "Початковй ключ" msgid "Musician Credits" msgstr "Подяки музикантів" msgid "Mood" msgstr "Настрій" msgid "Original Album" msgstr "Оригінальна назва альбому" msgid "Original Filename" msgstr "Оригінальна назва файлу" msgid "Original Lyricist" msgstr "Оригінальне ім'я поета" msgid "Original Artist" msgstr "Оригінальне ім'я виконавця" msgid "File Owner" msgstr "Власник файлу" msgid "Band/Orchestra" msgstr "Гурт/оркестр" msgid "Interpreted/Remixed" msgstr "Інтерпретація/Ремікс" msgid "Part Of A Set" msgstr "Частина набору" msgid "Produced" msgstr "Продюсер" msgid "Internet Radio Station Name" msgstr "Назва інтернет-радіостанції" msgid "Internet Radio Station Owner" msgstr "Власник інтернет-раідостанції" msgid "Album Sort Order" msgstr "Порядок сортування альбомів" msgid "Performer Sort Order" msgstr "Порядок сортування виконавців" msgid "Title Sort Order" msgstr "Порядок сортування назв" msgid "Software" msgstr "Програма" msgid "Set Subtitle" msgstr "Встановити підзаголовок" msgid "User Defined Text" msgstr "Текст користувача" msgid "Commercial Information" msgstr "Комерційна інформація" msgid "Copyright/Legal Information" msgstr "Авторське право/юридична інформація" msgid "Official Audio File Website" msgstr "Офіційна веб-сторінка аудіофайлу" msgid "Official Artist Website" msgstr "Офіційна веб-сторінка виконавця" msgid "Official Audio Source Website" msgstr "Офіційна веб-сторінка джерела аудіо" msgid "Official Radio Station Website" msgstr "Офіційна веб-сторінка радіостанції" msgid "Payment" msgstr "Сплата" msgid "Publisher's Official Website" msgstr "Офіційна веб-сторінка видавця" msgid "User Defined URL" msgstr "URL користувача" msgid "Vendor" msgstr "Постачальник" msgid "ReplayGain Reference Loudness" msgstr "Опорна гучність Вирівнювання Гучності (ReplayGain)" msgid "ReplayGain Track Gain" msgstr "Коефіцієнт підсилення доріжки для вирівнювання гучності (ReplayGain)" msgid "ReplayGain Track Peak" msgstr "Пік доріжки для вирівнювання гучності (ReplayGain)" msgid "ReplayGain Album Gain" msgstr "Коефіцієнт підсилення альбома для вирівнювання гучності (ReplayGain)" msgid "ReplayGain Album Peak" msgstr "Пік альбома для вирівнювання гучності (ReplayGain)" msgid "Icy-Name" msgstr "Назва станції (Icy-Name)" msgid "Icy-Description" msgstr "Опис станції (Icy-Description)" msgid "Icy-Genre" msgstr "Жанр станції (Icy-Genre)" msgid "RVA" msgstr "АВГ (RVA)" msgid "Attached Picture" msgstr "Прикріплена картинка" msgid "Binary Object" msgstr "Бінарний об'єкт" msgid "NULL" msgstr "NULL" msgid "ID3v1" msgstr "ID3v1" msgid "ID3v2" msgstr "ID3v2" msgid "APE" msgstr "APE" msgid "Ogg Xiph Comments" msgstr "Коментарі Ogg Xiph" msgid "FLAC Pictures" msgstr "Картинки FLAC" msgid "Musepack ReplayGain" msgstr "Вирівнювання гучності Musepack" msgid "Generic StreamMeta" msgstr "Загалні метадані потоку" msgid "MPEG StreamMeta" msgstr "Метадані MPEG-потоку" msgid "Module info" msgstr "Інформація про модуль" msgid "Unknown" msgstr "Невідомий" msgid "Other" msgstr "Інше" msgid "File icon (32x32 PNG)" msgstr "Іконка файлу (32x32 PNG)" msgid "File icon (other)" msgstr "Значок файлу (інше)" msgid "Front cover" msgstr "Передня обкладинка" msgid "Back cover" msgstr "Задня обкладинка" msgid "Leaflet page" msgstr "Вкладиш" msgid "Album image" msgstr "Зображення альбому" msgid "Lead artist/performer" msgstr "Ведучий співак/виконавець" msgid "Artist/performer" msgstr "Співак/виконавець" msgid "Band/orchestra" msgstr "Гурт/оркестр" msgid "Lyricist/text writer" msgstr "Поет/автор тексту" msgid "Recording location/studio" msgstr "Місце запису/студія" msgid "During recording" msgstr "Під час запису" msgid "During performance" msgstr "Під час виконання" msgid "Movie/video screen capture" msgstr "Кадр з кіно/відеофільму" msgid "A large, coloured fish" msgstr "Велика кольорова риба" msgid "Illustration" msgstr "Ілюстрація" msgid "Band/artist logotype" msgstr "Логотип гурту/виконавця" msgid "Publisher/studio logotype" msgstr "Логотип видавця/студії" msgid "Music Store" msgstr "Музичне Сховище" msgid "Search..." msgstr "Шукати..." msgid "Collapse all items" msgstr "Згорнути усі елементи" msgid "Edit item..." msgstr "Редагувати елемент..." msgid "Add item..." msgstr "Додати елемент..." msgid "Remove item..." msgstr "Видалити елемент..." msgid "Save all stores" msgstr "Зберегти всі сховища" msgid "Create empty store..." msgstr "Створити порожнє сховище..." msgid "*Music Store" msgstr "*Музичне Сховище" #, c-format msgid "Do you want to save store \"%s\" before removing from Music Store?" msgstr "Бажаєте зберегти сховище \"%s\" перед видаленням з Музичного Сховища?" msgid "You will need to restart Aqualung for the following changes to take effect:" msgstr "Вам знадобиться перезапустити Aqualung, щоб набули чинності наступні зміни:" msgid "Select a font..." msgstr "Обрати шрифт..." msgid "Disable skin support" msgstr "Вимкнути підтримку жупанів" msgid "rw" msgstr "читання/запис" msgid "r" msgstr "тільки читання" msgid "unreachable" msgstr "недосяжний" msgid "Please select a Programable Title Format File." msgstr "Будь ласка, оберіть файл програмованого форматування заголовка." msgid "Please select a Music Store database." msgstr "Будьласка оберіть базу даних Музичного Сховища." msgid "Paths must either be absolute or starting with a tilde." msgstr "Шляхи мають бути абсолютними або починатися із тильди." msgid "The specified store has already been added to the list." msgstr "Вказане сховище вже додано до списку." #, c-format msgid "" "\n" "The template string you enter here will be used to construct a single title line from an Artist, a Record and a Track name. These are denoted by %%%%a, %%%%r and %%%%t, respectively.\n" msgstr "" "\n" "Рядки шаблону, що ви впишете сюди, буде використано для складання однієї назви з Виконавця, Запису та назви Доріжки. Вони позначаються %%%%a, %%%%r та %%%%t, відповідно.\n" msgid "" "\n" "The file you enter/choose here will set the Lua program to use to format the title. See the Aqualung manual for details. Here is a quick example of what you can use in the file:\n" "\n" "function playlist_title()\n" " return m('artist') .. '-' .. m('title') .. ' (' .. m('album') .. ') (' .. i('filename') .. ')'\n" "end" msgstr "" "\n" "Файл, що ви уведете/оберете тут, встановить програму на Lua, що буде використана для форматування заголовка. Для додаткової інформації див. довідку з Aqualung. Ось швидкий прклад того, що ви можете використовувати у цьому файлі:\n" "\n" "function playlist_title()\n" " return m('artist') .. '-' .. m('title') .. ' (' .. m('album') .. ') (' .. i('filename') .. ')'\n" "end" msgid "" "\n" "The string you enter here will be parsed as a command line before parsing the actual command line parameters. What you enter here will act as a default setting and may or may not be overridden from the 'real' command line.\n" "\n" "Example: enter '-o alsa -R' below to use ALSA output running realtime as a default.\n" msgstr "" "\n" "Рядок, що ви введете тут буде проаналізовано як командний рядок перед аналізом параметрів справжнього командного рядку. Те, що ви впишете тут, буде діяти як налаштування за замовчуванням, та може бути або не бути скасовано 'справжнім' командним рядком.\n" "Приклад: впишіть '-o alsa -R' нижче для використання виводу через ALSA у реальному часі за замовчуванням.\n" msgid "" "Paths must either be absolute or starting with a tilde, which will be expanded to the user's home directory.\n" "\n" "Drag and drop entries in the list to set the store order in the Music Store." msgstr "" "Шляхи мають бути абсолютними або починатися із тильди, яку буде перетворено на домашній каталог користувача.\n" "\n" "Перетягніть записи у списку, щоб встановити порядок зберігання у Музичному Сховищі." msgid "" "\n" "Set the drive speed for CD playing in CD-ROM speed units. One speed unit equals to 176 kBps raw data reading speed. Warning: not all drives honor this setting.\n" "\n" "Lower speed usually means less drive noise. However, when using Paranoia error correction modes for increased accuracy, generally much larger speeds are required to prevent buffer underruns (and thus audible drop-outs).\n" "\n" "Please note that these settings do not apply to CD Ripping, which always happens with maximum available speed and with error correction modes manually set before every run." msgstr "" "\n" "Встановіть швидкість приводу для програвання CD в одиницях швидкості CD-ROM. Одна одиниця швидкості відповідає швидкості читання даних 176 кбіт/с. Попередження: не всі пристрої приймають це налаштування.\n" "\n" "Нижча швидкість зазвичай означає менше галасу з боку приводу. Однак, коли використовуються режими корекції помилок Paranoia для підвищення точності, звичайно потрібні набагато більші швидкості, аби запобігти спустошенню буфера (і як наслідок - чутних випадань).\n" "\n" "Будь ласка, зауважте, що ці налаштування не впливають на діставання музики з CD (Ripping), яке завжди відбувається на максимально можливій швидкості та з ручним встановленням режимів корекції помилок перед кожним сеансом." msgid "" "\n" "Most drives let Aqualung know when a CD has been inserted or removed by providing a 'media changed' flag. However, some drives don't set this flag properly, and thus it may happen that a newly inserted CD remains unnoticed to Aqualung. In such cases, enabling this option should help." msgstr "" "\n" "Більшість пристроїв дають Aqualung'у знати, коли вставлено або вилучено CD, встановлюючи прапор 'носій змінено'. Однак, деякі пристрої не втановлюють цей флаг належним чином, і тому щойно вставлений CD може лишитися непоміченим Aqualung'ом. В таких випадках увімкнення цієї функції має допомогти." msgid "" "\n" "Here you should enter a comma-separated list of domains\n" "that should be accessed without using the proxy set above.\n" "Example: localhost, .localdomain, .my.domain.com" msgstr "" "\n" "Тут ви маєте увести через кому список доменів,\n" "доступ до яких має здійсньватися без використання\n" "проксі, встановленого вище.\n" "Приклад: localhost, .localdomain, .my.domain.com" msgid "Embed playlist into main window" msgstr "Вбудувати список програвання у головне вікно" msgid "Enable systray" msgstr "Увімкнути системний лоток" msgid "Do nothing" msgstr "Нічого не робити" msgid "Change volume" msgstr "Змінити гучність" msgid "Change balance" msgstr "Змінити баланс" msgid "Change song position" msgstr "Змінити позицію пісні" msgid "Change current song" msgstr "Змінити поточну пісню" msgid "Left button" msgstr "Ліва клавіша" msgid "Middle button" msgstr "Середня клавіша" msgid "Right button" msgstr "Права клавіша" msgid "Button" msgstr "Клавіша" msgid "Left and right mouse buttons are reserved." msgstr "Ліву та праву клавіші миші зарезервовано." msgid "This button is already assigned." msgstr "Цю клавішу вже призначено." msgid "Add mouse button command" msgstr "Додати команду клавіші миші" msgid "Mouse button" msgstr "Клавіша миші" msgid "Click here to set mouse button" msgstr "Клацніть тут, щоб встановити клавішу миші" msgid "Command" msgstr "Команда" msgid "Main window" msgstr "Головне вікно" msgid "Disable control buttons relief" msgstr "Вимкнути рельєф кнопок керування" msgid "Combine play and pause buttons" msgstr "Об'єднати кнопки паузи ті відтворення" msgid "Keep main window always on top" msgstr "Розміщувати головне вікно завжди зверху" msgid "Show song name in the main window's title" msgstr "Показувати назву пісні у заголовку головного вікна" msgid "Title Format" msgstr "Формат назви" msgid "Programmable title format file" msgstr "Файл програмованого форматування заголовка" msgid "Systray" msgstr "Системний лоток" msgid "Start minimized" msgstr "Запускати мінімізованим" msgid "Play/Stop song" msgstr "Грати/Зупинити пісню" msgid "Play/Pause song" msgstr "Програвати/Зупинити пісню" msgid "Mouse wheel" msgstr "Колесо миші" msgid "Vertical mouse wheel:" msgstr "Вертикальне колесо миші:" msgid "Horizontal mouse wheel:" msgstr "Горизонтальне колесо миші:" msgid "Mouse buttons" msgstr "Клавіші миші" msgid "Miscellaneous" msgstr "Різне" msgid "Implicit command line" msgstr "Неявний командний рядок" msgid "Cover art" msgstr "Обкладинка" msgid "Default cover width:" msgstr "Ширина обкладинки за замовчуванням:" msgid "50 pixels" msgstr "50 пікселів" msgid "100 pixels" msgstr "100 пікселів" msgid "200 pixels" msgstr "200 пікселів" msgid "300 pixels" msgstr "300 пікселів" msgid "use browser window width" msgstr "використовувати ширину вікна оглядача" msgid "Do not magnify images with smaller width" msgstr "Не збільшувати зображення меншої ширини" msgid "Show cover thumbnail for Music Store tracks only" msgstr "Показувати мініатюру обкладинки тільки для треків з Музичного Сховища" msgid "Don't show cover thumbnail in the main window" msgstr "Не показувати мініатюру обкладинки у головному вікні" msgid "Enable tooltips" msgstr "Увімкнути підказки" msgid "Simple view in LADSPA patch builder" msgstr "Спрощений вигляд будівельника патчів LADSPA" msgid "United windows minimization" msgstr "Об'єднана мінімізація вікон" msgid "Show hidden files and directories in file choosers" msgstr "Показувати приховані файли та каталоги у діалогах вибору файу" msgid "Show tags tab first in the file info dialog" msgstr "Показувати вкладку тегів першою у вікні інформації про файл" msgid "Playlist" msgstr "Список програвання" msgid "Put control buttons at the bottom of playlist" msgstr "Кнопки керування знизу списку програвання" msgid "Save and restore the playlist on exit/startup" msgstr "Запис та відновлення списку програвання при виході/запуску" msgid "Save playlist periodically [min]:" msgstr "Періодично зберігати список програвання [хвил.]:" msgid "Album mode is the default when adding entire records" msgstr "Режим альбому використовується за замовчуванням при додаванні цілих записів" msgid "Always show the tab bar" msgstr "Завжди показувати рядок вкладок" msgid "Show close button in tab" msgstr "Показувати кнопку закриття на вкладці" msgid "When shuffling, records added in Album mode are played in order" msgstr "У режимі перемішування записи, додані в режимі альбому, програються по черзі" msgid "Enable statusbar" msgstr "Увімкнути рядок стану" msgid "Enable statusbar in playlist" msgstr "Увімкнути рядок стану у списку програвання" msgid "Show soundfile size in statusbar" msgstr "Показувати розмір файлу у статусному рядку" msgid "Show RVA values" msgstr "Показати значення RVA" msgid "Show track lengths" msgstr "Показати тривалість доріжок" msgid "Show active track name in bold" msgstr "Виділяти жирним активну доріжку" msgid "Automatically roll to active track" msgstr "Автоматично переміщатися до активної доріжки" msgid "Enable rules hint" msgstr "Переміжний колір рядків у списку" msgid "Playlist column order" msgstr "Порядок стовпчиків списку пргравання" msgid "" "Drag and drop entries in the list below \n" "to set the column order in the Playlist." msgstr "" "Перетягуйте пункти у списку нижче для \n" "встановлення порядку стовпчиків у списку пргравання." msgid "Column" msgstr "Стовпчик" msgid "Track titles" msgstr "Назви доріжок" msgid "RVA values" msgstr "Значення RVA" msgid "Track lengths" msgstr "Довжина доріжок" msgid "Hide comment pane" msgstr "Приховати панель коментарів" msgid "Hide the Music Store comment pane" msgstr "Приховати панель коментарів Музичного Складу" msgid "Enable toolbar" msgstr "Увімкнути панель інструментів" msgid "Enable toolbar in Music Store" msgstr "Увімкнути панель інструментів у Музичному Сховищі" msgid "Enable statusbar in Music Store" msgstr "Увімкнути рядок стану у Музичному Сховищі" msgid "Expand Stores on startup" msgstr "Розгорнути сховища після запуску" msgid "Enable tree node icons" msgstr "Дозволити значки вузлів дерева" msgid "Enable Music Store tree node icons" msgstr "Дозволити значки вузлів дерева Музичного Сховища" msgid "Ask for confirmation when removing items" msgstr "Запитувати підтвердження при видаленні елементів" msgid "Paths to Music Store databases" msgstr "Шляхи до баз даних Музичного Сховища" msgid "Path" msgstr "Шлях" msgid "Access" msgstr "Доступ" msgid "Refresh" msgstr "Оновити" msgid "DSP" msgstr "DSP" msgid "LADSPA plugin processing" msgstr "Обробка додатку LADSPA" msgid "Pre Fader (before Volume & Balance)" msgstr "Передпідсилювач (до Гучності та Баланса)" msgid "Post Fader (after Volume & Balance)" msgstr "Постпідсилювач (після Гучності та Баланса)" msgid "" "Aqualung is compiled without LADSPA plugin support.\n" "See the About box and the documentation for details." msgstr "" "Aqualung скомпільовано без підтримки додатків LADSPA.\n" "Дивись вікно 'Про програму' та документацію для подробиць." msgid "Sample Rate Converter type" msgstr "Тип перетворювача частоти дискретизації" msgid "" "Aqualung is compiled without Sample Rate Converter support.\n" "See the About box and the documentation for details." msgstr "" "Aqualung скомпільовано без підтримки Перетворювача Частоти Дискретизації.\n" "Дивись вікно 'Про програму' та документацію для подробиць." msgid "Playback RVA" msgstr "АВГ (RVA)" msgid "Enable playback RVA" msgstr "Задіяти Автоматичне Вирівнювання Гучності (RVA)" msgid "Listening environment:" msgstr "Оточення прослуховування:" msgid "Audiophile" msgstr "Аудіофіл" msgid "Living room" msgstr "Вітальня" msgid "Office" msgstr "Офіс" msgid "Noisy workshop" msgstr "Галаслива майстерня" msgid "Reference volume [dBFS] :" msgstr "Опорний рівень [дБ повна шкала] :" msgid "Steepness [dB/dB] :" msgstr "Крутість [дБ/дБ] :" msgid "RVA for Unmeasured Files [dB] :" msgstr "Рівень RVA для незміряних файлів [дБ] :" msgid "Apply averaged RVA to tracks of the same record" msgstr "Застосувати усереднений рівень RVA до доріжок одного запису" msgid "Drop statistical aberrations based on" msgstr "Нехтувати випадковими відхиленнями, базуючись на" #, no-c-format msgid "% of standard deviation" msgstr "% від стандартного відхилення" msgid "Linear threshold [dB]" msgstr "Лінійному порозі [дБ]" msgid "Linear threshold [dB] :" msgstr "Лінійний поріг [дБ] :" #, no-c-format msgid "% of standard deviation :" msgstr "% від стандартного відхилення :" msgid "ReplayGain tag to use (with fallback to the other): " msgstr "Тег ReplayGain для використання (із відходом на інший):" msgid "Replaygain_track_gain" msgstr "Replaygain_track_gain" msgid "Replaygain_album_gain" msgstr "Replaygain_track_gain" msgid "Adding files to Playlist" msgstr "Додавання файлів до списку програвання" msgid "" "Use basename only instead of full path\n" "if no metadata is available." msgstr "" "Використовувати тільки базове ім'я замість\n" "повного шляху,якщо не доступні метадані." msgid "Metadata editor (File info dialog)" msgstr "Редактор метаданих (діалог інформації про файл)" msgid "" "When adding new frames, try to set their contents\n" "from another tag's equivalent frame." msgstr "" "При додаванні нових полів намагатися встановити їх вміст\n" "з еквівалентних полів іншого тега." msgid "Batch update & encode (mass tagger, CD ripper, file export)" msgstr "Пакетне оновлення та кодування (масове заповнення тегів, діставання з CD, експорт файлів)" msgid "Tags to add when creating or updating MPEG audio files:" msgstr "Теги, які додавати при створенні чи зміні аудіофайлів MPEG:" msgid "" "Note: pre-existing tags will be updated even though they\n" "might not be checked here." msgstr "" "Зауваження: існуючі теги будуть оновлені навіть якщо вони\n" "не обрані тут." msgid "CD Audio" msgstr "CD Audio" msgid "CD drive speed:" msgstr "Швидкість приводу CD:" msgid "\tMaximum number of retries:" msgstr "\tМаксимальна кількість спроб:" msgid "Force TOC re-read on every drive scan" msgstr "Примусово перечитувати таблицю файлів при кожному скануванні диску" msgid "Automatically add CDs to Playlist" msgstr "Автоматично додавати CD до списку програвання" msgid "Automatically remove CDs from Playlist" msgstr "Автоматично видаляти CD зі списку програвання" msgid "CDDB server:" msgstr "Сервер CDDB:" msgid "Connection timeout [sec]:" msgstr "Таймаут з'єднання [сек]:" msgid "Email address for submission:" msgstr "Адреса електроної пошти для підписки:" msgid "Local CDDB directory:" msgstr "Локальний каталог CDDB:" msgid "Use the local database only" msgstr "Використовувати лише локальну базу даних" msgid "Protocol for querying (direct connection only):" msgstr "Протокол для запитів (лише пряме з'єднання):" msgid "CDDBP (port 888)" msgstr "CDDBP (порт 888)" msgid "HTTP (port 80)" msgstr "HTTP (порт 80)" msgid "Internet" msgstr "Інтернет" msgid "Direct connection to the Internet" msgstr "Пряме з'єеднання з Інтернетом" msgid "Connect via HTTP proxy" msgstr "З'єднання через HTTP-проксі" msgid "Proxy settings" msgstr "Налаштування проксі" msgid "Proxy host:" msgstr "Адреса проксі:" msgid "Port:" msgstr "Порт:" msgid "No proxy for:" msgstr "Не використовувати проксі для:" msgid "Timeout for socket I/O:" msgstr "Час очікування вводу/виводу сокета:" msgid "seconds" msgstr "секунд" msgid "Appearance" msgstr "Вигляд" msgid "Override skin settings" msgstr "Перекривати установки жупана" msgid "Fonts" msgstr "Шрифти" msgid "Playlist: " msgstr "Список програвання: " msgid "Music Store: " msgstr "Музичне Сховище: " msgid "Big timer: " msgstr "Великий таймер: " msgid "Small timers: " msgstr "Маленькі таймери:" msgid "Song title: " msgstr "Назва пісні: " msgid "Song info: " msgstr "Інформація про пісню:" msgid "Statusbar: " msgstr "Статусний рядок:" msgid "Colors" msgstr "Кольори" msgid "Song in playlist: " msgstr "Пісня у списку програвання: " msgid "Active song in playlist: " msgstr "Активна пісня у списку програвання: " msgid "Error in title format string" msgstr "Помилка у рядку формату заголовка" msgid "(Untitled)" msgstr "(Без назви)" #, c-format msgid " (%d/%d)" msgstr " (%d/%d)" msgid "Select files" msgstr "Обрати файли" msgid "Select directory" msgstr "Обрати каталог" msgid "Add URL" msgstr "Додати URL" msgid "URL:" msgstr "URL:" msgid "Please specify the file to save the playlist to." msgstr "Будь ласка, вкажіть файл для збереження списку програвання." msgid "Please specify the file to load the playlist from." msgstr "Будь ласка, вкажіть файл, з якого буде завантажено список програвання." msgid "" "Playback RVA is currently disabled.\n" "Do you want to enable it now?" msgstr "" "АВГ (RVA) зараз вимкнено.\n" "Бажаєте увімкнути його зараз?" msgid "counting..." msgstr "підрахунок..." msgid "track" msgstr "доріжка" msgid "tracks" msgstr "доріжки" msgid "Rename playlist" msgstr "Перейменувати список програвання" msgid "Name:" msgstr "Ім'я:" msgid "New tab" msgstr "Нова вкладка" msgid "Close tab" msgstr "Закрити вкладку" msgid "Undo close tab" msgstr "Скасувати закриття вкладки" msgid "Close other tabs" msgstr "Закрити інші вкладки" msgid " Selected: " msgstr " Обрані: " msgid "Total: " msgstr "Разом: " msgid "Add files" msgstr "Додати файли" msgid "" "Add files to playlist\n" "(Press right mouse button for menu)" msgstr "" "Додати файли до списку програвання\n" "(Натисніть праву кнопку миші для відкриття меню)" msgid "Select all" msgstr "Вибрати все" msgid "" "Select all songs in playlist\n" "(Press right mouse button for menu)" msgstr "" "Обрати усі пісні у списку програвання\n" "(Натисніть праву кнопку миші для відкриття меню)" msgid "Remove selected" msgstr "Видалити обрані" msgid "" "Remove selected songs from playlist\n" "(Press right mouse button for menu)" msgstr "" "Видалити обрані пісні зі списку програвання\n" "(Натисніть праву кнопку миші для відкриття меню)" msgid "Add directory" msgstr "Додати каталог" msgid "Select none" msgstr "Зняти вибір" msgid "Invert selection" msgstr "Перевернути вибір" msgid "Remove all" msgstr "Видалити всі" msgid "Remove dead" msgstr "Видалити мертві" msgid "Cut selected" msgstr "Вирізати обране" msgid "Save playlist" msgstr "Зберегти список програвання" msgid "Save all playlists" msgstr "Зберегти усі списки програвання" msgid "Load playlist in new tab" msgstr "Завантажити список програвання у нову вкладку" msgid "Load playlist" msgstr "Завантажити список програвання" msgid "Enqueue playlist" msgstr "Поставити в чергу список програвання" msgid "Send to iFP device" msgstr "Надіслати до пристрою iFP" msgid "Calculate RVA" msgstr "Підрахувати рівень RVA" msgid "Separate" msgstr "Окремо" msgid "Average" msgstr "Середній" msgid "Reread file metadata" msgstr "Перечитати матадані файлу" msgid "File info..." msgstr "Інформація про файл" msgid "Roll to active song" msgstr "Скотитися до активної пісні" msgid "Stop adding files" msgstr "Зупинити додавання файлів" msgid "Files selected for removal" msgstr "Обрані для видалення файли" msgid "Remove files" msgstr "Видалити файли" msgid "" "The selected files will be deleted from the filesystem. No recovery will be possible after this operation.\n" "\n" "Do you want to proceed?" msgstr "" "Обрані файли буде видалено з файлової системи. Відновлення буде неможливим після цієї операції.\n" "\n" "Бажаєте продовжити?" #, c-format msgid "Unable to remove %d file." msgstr "Неможливо видалити %d файл." #, c-format msgid "Unable to remove %d files." msgstr "Неможливо видалити %d файлів" msgid "LADSPA patch builder" msgstr "Будівельник патчів LADSPA" msgid "Available plugins" msgstr "Доступні розширення" msgid "ID" msgstr "ID" msgid "Category" msgstr "Категорія" msgid "Inputs" msgstr "Входи" msgid "Outputs" msgstr "Виходи" msgid "Running plugins" msgstr "Запущені розширення" msgid "_Configure" msgstr "_Налаштувати" msgid "Enable all plugins" msgstr "Задіяти усі розширення" msgid "Disable all plugins" msgstr "Вимкнути усі розширення" msgid "Invert current state" msgstr "Інвертувати поточний стан" msgid "Clear list" msgstr "Очистити список" msgid "Untitled" msgstr "Без назви" msgid "JACK Port Setup" msgstr "Налаштування порту JACK" msgid "Rescan" msgstr "Пресканувати" msgid "Available connections" msgstr "Доступні з'єднання" msgid "Clear connections" msgstr "Очистити з'єднання" msgid " out L" msgstr " вихід Л" msgid " out R" msgstr " вихід П" msgid "Search the Music Store" msgstr "Пошук Музичному Сховищі" msgid "Key: " msgstr "Ключ: " msgid "Case sensitive" msgstr "Враховувати регістр" msgid "Exact matches only" msgstr "Тільки повний збіг" msgid "Select first and close window" msgstr "Обрати перший та закрити вікно" msgid "Search in:" msgstr "Шукати у:" msgid "Artist names" msgstr "Іменах виконавців" msgid "Record titles" msgstr "Назвах записів" msgid "Comments" msgstr "Коментарях" msgid "Search" msgstr "Шукати" msgid "Search the Playlist" msgstr "Шукати у списку програвання" msgid "Available skins" msgstr "Наявні жупани" msgid "Drive info" msgstr "Інформація приводу" msgid "Device path:" msgstr "Шлях до пристрою:" msgid "Vendor:" msgstr "Постачальник:" msgid "Revision:" msgstr "Перегляд:" msgid "" "The information below is reported by the drive, and\n" "may not reflect the actual capabilities of the device." msgstr "" "Інформація нижче отримана з приладу і\n" "може не відображати дійсних можливостей приладу." msgid "Eject" msgstr "Витягти" msgid "Close tray" msgstr "Зачинити лоток" msgid "Disable manual eject" msgstr "Заборонити ручне витягування" msgid "Select juke-box disc" msgstr "Обрати диск у CD-чейнджері" msgid "Set drive speed" msgstr "Встановити швидкість приводу" msgid "Detect media change" msgstr "Виявляти зміну носія" msgid "Read multiple sessions" msgstr "Зчитувати кілька сесій" msgid "Hard reset device" msgstr "Жорстко скинути пристрій" msgid "Reading" msgstr "Читання" msgid "Play CD Audio" msgstr "Грати CD Audio" msgid "Read CD-DA" msgstr "Читати CD-DA" msgid "Read CD+G" msgstr "Читати CD+G" msgid "Read CD-R" msgstr "Читати CD-R" msgid "Read CD-RW" msgstr "Читати CD-RW" msgid "Read DVD-R" msgstr "Читати DVD-R" msgid "Read DVD+R" msgstr "Читати DVD+R" msgid "Read DVD-RW" msgstr "Читати DVD-RW" msgid "Read DVD+RW" msgstr "Читати DVD+RW" msgid "Read DVD-RAM" msgstr "Читати DVD-RAM" msgid "Read DVD-ROM" msgstr "Читати DVD-ROM" msgid "C2 Error Correction" msgstr "Корекція помилок C2" msgid "Read Mode 2 Form 1" msgstr "Читання Mode 2 Form 1" msgid "Read Mode 2 Form 2" msgstr "Читання Mode 2 Form 2" msgid "Read MCN" msgstr "Зчитувати MCN" msgid "Read ISRC" msgstr "Зчитувати ISRC (Міжнародний стандартний номер запису)" msgid "Writing" msgstr "Запис" msgid "Write CD-R" msgstr "Записати CD-R" msgid "Write CD-RW" msgstr "Записати CD-RW" msgid "Write DVD-R" msgstr "Записати DVD-R" msgid "Write DVD+R" msgstr "Записати DVD+R" msgid "Write DVD-RW" msgstr "Записати DVD-RW" msgid "Write DVD+RW" msgstr "Записати DVD+RW" msgid "Write DVD-RAM" msgstr "Записати DVD-RAM" msgid "Mount Rainier" msgstr "Пакетний запис (Mount Rainier)" msgid "Burn Proof" msgstr "Захист від запису" msgid "Disc info" msgstr "Інформація про диск" msgid "This CD does not contain CD-Text information." msgstr "Цей диск не містить інформації CD-Text" msgid "drive" msgstr "диск" msgid "drives" msgstr "диски" msgid "record" msgstr "запис" msgid "records" msgstr "записи" msgid "Add to playlist" msgstr "Додати до списку програвання" msgid "Add to playlist (Album mode)" msgstr "Додати до списку програвання (режим альбому)" msgid "CDDB query for this CD..." msgstr "Запит у CDDB для цього CD..." msgid "Submit CD to CDDB database..." msgstr "Надіслати дані про цей CD до бази даних CDDB..." msgid "Rip CD..." msgstr "Дістати музику з CD..." msgid "Disc info..." msgstr "Інформація про диск..." msgid "Drive info..." msgstr "Інформація приводу..." msgid "Comments:" msgstr "Коментарі:" msgid "Please select the xml file for this store." msgstr "Будьласка оберіть xml файл для цього складу." msgid "Create empty store" msgstr "Створити пусте сховище" msgid "Visible name:" msgstr "Видиме ім'я:" msgid "Edit Store" msgstr "Редагувати Сховище" msgid "Use relative paths in store file" msgstr "Використовувати відносні шляхи у файлі сховища" msgid "Add Artist" msgstr "Додати виконавця" msgid "Name to sort by:" msgstr "Ім'я для сортування:" msgid "Edit Artist" msgstr "Редагувати виконавця" msgid "Please select the audio files for this record." msgstr "Будь ласка, оберіть аудіофайли для цього запису." msgid "Add Record" msgstr "Додати запис" msgid "Auto-create tracks from these files:" msgstr "Автоматично створити доріжки з цих файлів:" msgid "_Add files..." msgstr "_Додати файли..." msgid "Edit Record" msgstr "Редагувати запис" msgid "Please select the audio file for this track." msgstr "Будь ласка, оберіть аудіофайл для цієї доріжки." msgid "Add Track" msgstr "Додати доріжку" msgid "Edit Track" msgstr "Редагувати доріжку" msgid "Duration:" msgstr "Тривалість:" #, c-format msgid "Unmeasured" msgstr "Невиміряно" msgid "Volume level:" msgstr "Рівень гучності:" msgid "Use manual RVA value [dB]" msgstr "Використовувати свій рівень RVA [дБ]" #, c-format msgid "Really remove \"%s\" from the Music Store?" msgstr "Справді видалити \"%s\" з Музичного Сховища?" msgid "Stop adding songs" msgstr "Зупинити додавання пісень" #, c-format msgid "" "The store '%s' already exists.\n" "Add it on the Settings/Music Store tab." msgstr "" "Сховище '%s' вже існує.\n" "Додайте його на вкладці Налаштування/Музичне Сховище." #, c-format msgid "Really remove store \"%s\" from the Music Store?" msgstr "Справді видалити сховище \"%s\" з Музичного Сховища?" msgid "Remove Store" msgstr "Видалити Сховище" msgid "Do you want to save the store before removing?" msgstr "Бажаєте зберегти сховище перед видаленням?" msgid "Remove Artist" msgstr "Вадалити виконавця" msgid "Remove Record" msgstr "Видалити запис" msgid "Remove Track" msgstr "Видалити доріжку" msgid "Update file metadata" msgstr "Оновити метадані файлу" msgid "Track name" msgstr "Назва доріжки" msgid "Track comment" msgstr "Коментар доріжки" msgid "Track number" msgstr "Номер доріжки" msgid "Failed to set metadata for the following files:" msgstr "Неможливо встановити метадані для наступних файлів:" msgid "Filename" msgstr "Назва файлу" msgid "Reason" msgstr "Причина" msgid "(no comment)" msgstr "(без коментаря)" msgid "artist" msgstr "виконавець" msgid "artists" msgstr "виконавці" #, c-format msgid "File \"%s\" does not exist or your write permission has been withdrawn. Check if the partition containing the store file has been unmounted." msgstr "Файл \"%s\" не існує, або вас позбавлено права на його запис. Перевірте, чи не відмонтовано розділ, що містить файл сховища." msgid "Build / Update store from filesystem..." msgstr "Побудувати/Оновити сховище з файлової системи..." msgid "Edit store..." msgstr "Редагувати сховище..." msgid "Export store..." msgstr "Експорт сховища..." msgid "Save store" msgstr "Зберегти сховище" msgid "Remove store" msgstr "Видалити сховище" msgid "Add new artist to this store..." msgstr "Додати нового виконавця до цього сховища..." msgid "Calculate volume (recursive)" msgstr "Підрахувати гучність (рекурсивно)" msgid "Unmeasured tracks only" msgstr "Тільки невиміряних доріжок" msgid "All tracks" msgstr "Усіх доріжок" msgid "Batch-update file metadata..." msgstr "Пакетне оновлення метаданих файлів..." msgid "Add new artist..." msgstr "Додати нового виконавця..." msgid "Edit artist..." msgstr "Редагувати виконавця..." msgid "Export artist..." msgstr "Експорт виконавця..." msgid "Remove artist" msgstr "Видалити виконавця" msgid "Add new record to this artist..." msgstr "Додати новий запис до цього виконавця..." msgid "Add new record..." msgstr "Додати новий запис..." msgid "Edit record..." msgstr "Редагувати запис..." msgid "Export record..." msgstr "Експорт запису..." msgid "Remove record" msgstr "Видалити запис" msgid "Add new track to this record..." msgstr "Додати нову доріжку до цього запису..." msgid "CDDB query for this record..." msgstr "Запит у CDDB для цього запису..." msgid "Submit record to CDDB database..." msgstr "Надіслати запис до бази даних CDDB..." msgid "Add new track..." msgstr "Додати нову доріжку..." msgid "Edit track..." msgstr "Редагувати доріжку..." msgid "Export track..." msgstr "Експорт доріжки..." msgid "Remove track" msgstr "Видалити доріжку" msgid "Calculate volume" msgstr "Підрахувати гучність" msgid "Only if unmeasured" msgstr "Тільки якщо не виміряно" msgid "In any case" msgstr "У будь-якому разі" msgid "Update file metadata..." msgstr "Оновити метадані файлів..." msgid "Please select the download directory for this podcast." msgstr "Будь ласка, оберіть каталог завантаження для цього подкаста." msgid "Subscribe to new feed" msgstr "Підписатися на нову стрічку" msgid "Edit feed settings" msgstr "Редагувати властивості стрічки" msgid "Podcast URL:" msgstr "URL подкаста:" msgid "Download directory:" msgstr "Каталог завантаження:" msgid "Auto-check interval [hour]:" msgstr "Інтервал автомеревірки [годин]:" msgid "" "Automatic update has been disabled for all feeds\n" "in the Podcasts store popup menu." msgstr "" "Автоматичне оновлення заборонено для усіх стрічок\n" "у спливаючому меню сховища подкастів." msgid "Limits" msgstr "Межі" msgid "Maximum number of items:" msgstr "Максимальна кількість елементів:" msgid "Remove older items [day]:" msgstr "Видалити застарілі елементи [день]:" msgid "Maximum space to use [MB]:" msgstr "Максимальний використаний простір [Мб]:" msgid "Podcasts" msgstr "Подкасти" msgid "Updating..." msgstr "Оновлення..." msgid "Delete downloaded items from the filesystem" msgstr "Видалити завантажені елементи з файлової системи" msgid "Remove feed" msgstr "Видалити стрічку" #, c-format msgid "Really remove '%s' from the Music Store?" msgstr "Справді видалити \"%s\" з Музичного Сховища?" msgid "Reorder feeds" msgstr "Перевпорядкувати стрічки" msgid "" "Drag and drop entries in the list\n" "to set the feed order in the Music Store." msgstr "" "Перетягуйте пункти у списку для\n" "встановлення порядку стрічок у Музичному Сховищі." #, c-format msgid "Downloading %d/%d (%d%%) ..." msgstr "Завантаження %d/%d (%d%%) ..." msgid "item" msgstr "елемент" msgid "items" msgstr "елементи" msgid "new item" msgstr "новий елемент" msgid "new items" msgstr "нові елементи" msgid "feed" msgstr "стрічка" msgid "feeds" msgstr "стрічки" msgid "Export item..." msgstr "Експорт елементу..." msgid "Add all items to playlist" msgstr "Додати усі елементи до списку програвання" msgid "Add all items to playlist (Album mode)" msgstr "Додати усі елементи до списку програвання (режим альбому)" msgid "Add new items to playlist" msgstr "Додати нові елементи до списку програвання" msgid "Add new items to playlist (Album mode)" msgstr "Додати нові елементи до списку програвання (режим альбому)" msgid "Edit feed" msgstr "Редагувати стрічку" msgid "Export all items..." msgstr "Експорт усіх елементів..." msgid "Export new items..." msgstr "Експорт нових елементів..." msgid "Update feed" msgstr "Оновити стрічку" msgid "Abort ongoing update" msgstr "Перервати поточне оновлення" msgid "Update all feeds" msgstr "Оновити усі стрічки" msgid "Automatically update feeds" msgstr "Автоматично оновлювати стрічки" msgid "Unexpected end of string after '?'." msgstr "Неочикуваний кінець рядку після '?'." msgid "Expected '}' after '{', but end of string found." msgstr "Очикувалося '}' після '{', але знайдено кінець рядку." #, c-format msgid "Unknown conversion type character found after '%%%%'." msgstr "Після '%%%%' виявлено символ невідомого типу." msgid "Unknown conversion type character found after '?'." msgstr "Після '?' виявлено символ невідомого типу." msgid "day" msgstr "день" msgid "days" msgstr "дні" msgid "All Files" msgstr "Усі файли" msgid "Extended Title Format Files (*.lua)" msgstr "Файли розширеного форматування заголовка (*.lua)" msgid "Music Store Files (*.xml)" msgstr "Файли Музичного Сховища (*.xml)" msgid "Aqualung playlist (*.xml)" msgstr "Плей-ліст Aqualung (*.xml)" msgid "MP3 Playlist (*.m3u)" msgstr "Список програвання MP3 (*.m3u)" msgid "Multimedia Playlist (*.pls)" msgstr "Мультимедіа плей-ліст (*.pls)" msgid "All Playlist Files" msgstr "Усі файли списків програвання" msgid "All Audio Files" msgstr "Усі аудіофайли" msgid "Sound Files (*.wav, *.aiff, *.au, ...)" msgstr "Звукові файли (*.wav, *.aiff, *.au, ...)" msgid "Free Lossless Audio Codec (*.flac)" msgstr "Free Lossless Audio Codec (*.flac)" msgid "MPEG Audio (*.mp3, *.mpa, *.mpega, ...)" msgstr "MPEG Audio (*.mp3, *.mpa, *.mpega, ...)" msgid "Ogg Vorbis (*.ogg)" msgstr "Ogg Vorbis (*.ogg)" msgid "Ogg Speex (*.spx)" msgstr "Ogg Speex (*.spx)" msgid "Musepack (*.mpc)" msgstr "Musepack (*.mpc)" msgid "Monkey's Audio Codec (*.ape)" msgstr "Monkey's Audio Codec (*.ape)" msgid "Modules (*.xm, *.mod, *.it, *.s3m, ...)" msgstr "Модулі (*.xm, *.mod, *.it, *.s3m, ...)" msgid "Compressed modules (*.gz, *.bz2)" msgstr "Стиснуті модулі (*.gz, *.bz2)" msgid "Compressed modules (*.gz)" msgstr "Стиснуті модулі (*.gz)" msgid "Compressed modules (*.bz2)" msgstr "Стиснуті модулі (*.bz2)" msgid "WavPack (*.wv)" msgstr "WavPack (*.wv)" msgid "LAVC audio/video files" msgstr "LAVC аудіо/відео файли" msgid "Resume" msgstr "Поновити" msgid "Calculating volume level" msgstr "Підрахунок рівня гучності" msgid "Profile: Telephone" msgstr "Профіль: Телефон" msgid "Profile: Thumb" msgstr "Профіль: Ескіз" msgid "Profile: Radio" msgstr "Профіль: Радіо" msgid "Profile: Standard" msgstr "Профіль: Стандарт" msgid "Profile: Xtreme" msgstr "Профіль: Екстремальний" msgid "Profile: Insane" msgstr "Профіль: Божевільний" msgid "Profile: Braindead" msgstr "Профіль: Без башні" msgid "Layer I" msgstr "Шар I" msgid "Layer II" msgstr "Шар II" msgid "Layer III" msgstr "Шар III" msgid "Unrecognized" msgstr "Нерозпізнано" msgid "Single channel" msgstr "Один канал" msgid "Dual channel" msgstr "Два канала" msgid "Joint stereo" msgstr "Об'єднане стерео" msgid "Stereo" msgstr "Стерео" msgid "Emphasis: none" msgstr "Наголос: немає" msgid "Emphasis:" msgstr "Наголос:" msgid "Emphasis: reserved" msgstr "Наголос: резервний" msgid "bit signed" msgstr "біт знаковий" msgid "bit unsigned" msgstr "біт беззнаковий" msgid "bit float" msgstr "біт з рухомою комою" msgid "bit double" msgstr "біт подвійний" msgid "encoding" msgstr "кодування" msgid "Compression: Fast" msgstr "Стискання: Швидке" msgid "Compression: Normal" msgstr "Стискання: Нормальне" msgid "Compression: High" msgstr "Стискання: Сильне" msgid "Compression: Extra High" msgstr "Стискання: Дуже сильне" msgid "Compression: Insane" msgstr "Стискання: Божевільне" #~ msgid "Metadata (ID3, APE, Ogg comments)\n" #~ msgstr "Метадані (ID3, APE, Ogg comments)\n" #, fuzzy #~ msgid "No" #~ msgstr "Немає" #~ msgid "Rename directory" #~ msgstr "Перейменувати каталог" #~ msgid "Remove directory with its entire contents" #~ msgstr "Видалити каталог разом з усім вмістом" #, fuzzy #~ msgid "time unmeasured" #~ msgstr "час не виміряний" #~ msgid "" #~ "When adding to playlist, use file metadata (if available) instead of\n" #~ "information from the Music Store for:" #~ msgstr "" #~ "При додаванні до списку програвання, використовувати метадані\n" #~ "файла (якщо є) замість інформації з Музичного Сховища для:" #~ msgid "" #~ "When adding external files to playlist, use file metadata (if available) " #~ "for:" #~ msgstr "" #~ "При додаванні зовнішніх файлів до списку програвання, використовувати " #~ "метадані файла (якщо є) для:" #~ msgid "Replaygain tag to extract from Ogg Xiph and APE tags: " #~ msgstr "Тег Replaygain для діставання з Ogg Xiph та APE тегів: " #~ msgid "%d track [%s] (%.1f MB)" #~ msgstr "%d доріжок [%s] (%.1f МБ)" #~ msgid "%d track [%s] (%.1f GB)" #~ msgstr "%d доріжок [%s] (%.1f ГБ)" #~ msgid "%d track " #~ msgstr "%d доріжок" #~ msgid "%d track [%s] " #~ msgstr "%d доріжок [%s]" #~ msgid "%d tracks [%s] (%.1f MB)" #~ msgstr "%d доріжок [%s] (%.1f МБ)" #~ msgid "%d tracks [%s] (%.1f GB)" #~ msgstr "%d доріжок [%s] (%.1f ГБ)" #~ msgid "%d tracks " #~ msgstr "%d доріжок" #~ msgid "%d tracks [%s] " #~ msgstr "%d доріжок [%s]" #~ msgid "" #~ "All selected files will be deleted from the filesystem. No recovery will " #~ "be possible after this operation.\n" #~ "\n" #~ "Are you sure?" #~ msgstr "" #~ "Усі обрані файли буде видалено з файлової системи. Відновлення буде " #~ "неможливим після цієї операції.\n" #~ "\n" #~ "Ви впевнені?" #~ msgid "Type" #~ msgstr "Тип: " #~ msgid "Embedded picture" #~ msgstr "Вбудована картинка" #~ msgid "Save to file..." #~ msgstr "Зберегти до файлу" #~ msgid "Comment:" #~ msgstr "Коментар:" #~ msgid "Save basic fields" #~ msgstr "Зберегти основні поля" #, fuzzy #~ msgid "Relative Volume Adj.:" #~ msgstr "Рівень RVA:" #~ msgid "Remove ID3v1" #~ msgstr "Видалити ID3v1" #~ msgid "Create ID3v2" #~ msgstr "Створити ID3v2" #~ msgid "Remove ID3v2" #~ msgstr "Видалити ID3v2" #~ msgid "Create APE" #~ msgstr "Створити APE" #~ msgid "Remove APE" #~ msgstr "Видалити APE" #~ msgid "WavPack Metadata" #~ msgstr "Метадані WavPack" #~ msgid "Beats per minute" #~ msgstr "Ударів на хвилину" #~ msgid "Lyricist" #~ msgstr "Поет" #~ msgid "Length (ms)" #~ msgstr "Тривалість (мс):" #~ msgid "Owner/licensee" #~ msgstr "Власник/ліцензія" #~ msgid "Orchestra" #~ msgstr "Оркестр" #~ msgid "Artist sort order" #~ msgstr "Порядок сортування виконавців" aqualung-0.9beta11/src/po/de.mo0000644000175000001440000021661311331334313013250 00000000000000$,<8P9P4UPP/Q+MRFyT2U5V)X[X >ZIZRZhZ ~ZZZZZZZ ZZO[T[[[b[ i[ t[[[ [[ [[ [ [ [ [ \ \\3\J\b\t\\ \\\\ \\\\\\] ] !] ,]6]>]&X] ] ]9] ]]]^(^&B^ i^^^^^^^_'_E_^_d_ u_4____ __ _ _`A`A]` `/``hapbbb>b>b $c0c Hc(Uc~cc(ccRc$d -d 8dCdLd$hdRd!d&e")eLege}eeee e eeee e;f H S ] h s  Ð֐ ((>.g  ̑  Ò˒   , : G T _ m y $͓ G* r  ͔ޔ'E[4qҕ! 7 ANR Ycu  ɖ  (-@P-_ ! ȗח ޗ % 6@A И  *: CQa02ʙ) '+Ht #Ț ͚&ښ , 8EU&e  Лכܛ  +I![} ǜ ߜ7!$F Xe5jj Q7F/`&-  Ģ=բ=QXt ģ ң  * KQ Vbv#ޤ  .5<2r ,  % 6BW oC{ ٦( 9FMUks :V ?b ʨ ֨  9KW é Ωة  !-16<CLQV\"c ªǪͪ ֪0'"Ji ƫ̫ ӫ߫r$k.1įZeZMo` и۸ + 6AZuf! ( 5A^}  ú Һ ܺ  $E_  !׻  7C[m'5Tm%4!'5*1`+ھ3'M/u)Ͽտ F@GL ^k GII;R UU v&4 4GiX )/^D)+$>Wk   N-Es|  : 08 itz| "2 Ubw N-=$N s  $/3 cn"3&&-T [ e p| ! "7Iau~' B86$o )20$U\q$ "& ,7R6h RI/ yO 4C(] (  / 6P;X6/1fdp=7  6LTiz, A%K$q 2)@,X( ./M S_nH(&;1N H$8Pn% >2P3"Vg p}    " ?KRue :#6<sz"!  ' 1<Kek~,    )2 ;H_,y! "> S8a  !1 L"V(yN 3ATo 7C*V  $ %0 8 B MY h+r    /@p"79H W#d'$  #4X w *  &)?\ e s }   0DJOTt 0 a*lb v# !  *6Ir]\-+Am )/ 8 B)Mw9&  +5U ^i|I &(> g%s%.8%'EM79A@GA(8C,HpEKK\ent'%   +6F Ygx  99H\ t 1# , 6 A M X d p }  ..M7| ! 1 2:Ocl &<Nd8!^\o!  '=\r?-"B R] }    ! (6M eqy  29*dw  Y "e+$,> ^l|& >:,Q.~9)=FN#b' 1  8 D V e y     ' %  (6 _  u       ] (L  u   C  Z i =^ ` C 0A.r$ FF`# !* 0< K X bnt{ B # %.%T,z ;8V K   '1J]!{[! 2,!_  % *7BGvS!u CVR      '3CZ lw{  *&!*2 ; IWY_9e." # >KPV\mRY_sS?3V2(\J""`!${C 8{-'&V5/%.sa,-PUK 5~q B}LwwrUHY{X1z#(k eP*H@g8=b|k?cs[f*S,^o2B+B StD?h tx|~&yvdx=(Fk]>; U&GTe\ +k 64%4WoZP_|: mDCJ< ;!>lN/Dy^dJZ*^#:@m81dFp9_p`76OlLgv}n)GRidYbFha!B l|'5 # yMaO\Qft}v@/c3 08 ;{Nz1rXOP^bTW7\]LWCa:c@NDu"]MnRE`xhre(rZEo/6ijK'X<wp~.Lg:OjJ2F?.5.jVE`TX1f>pmQ"= A9zV)UA~<$qH3[jnE%Z GG,Y06u+ sQ4+&; $K[$q*3'Sz_i< -Q9 wIMA=l}gI02#n)yqfmIb]TMWK%i u,!A)CN9vo7Ic4-u>hteHR[ x70 Maximum number of retries: Destination directory is not read-write accessible! Here you should enter a comma-separated list of domains that should be accessed without using the proxy set above. Example: localhost, .localdomain, .my.domain.com Most drives let Aqualung know when a CD has been inserted or removed by providing a 'media changed' flag. However, some drives don't set this flag properly, and thus it may happen that a newly inserted CD remains unnoticed to Aqualung. In such cases, enabling this option should help. Set the drive speed for CD playing in CD-ROM speed units. One speed unit equals to 176 kBps raw data reading speed. Warning: not all drives honor this setting. Lower speed usually means less drive noise. However, when using Paranoia error correction modes for increased accuracy, generally much larger speeds are required to prevent buffer underruns (and thus audible drop-outs). Please note that these settings do not apply to CD Ripping, which always happens with maximum available speed and with error correction modes manually set before every run. The Music Store you selected has a matching Artist and Album, already containing some tracks. If you press OK, these tracks will be removed. The files themselves will be left intact, but they will be removed from the destination Music Store. Press Cancel to get back to change the Artist/Album or the destination Music Store. The file you enter/choose here will set the Lua program to use to format the title. See the Aqualung manual for details. Here is a quick example of what you can use in the file: function playlist_title() return m('artist') .. '-' .. m('title') .. ' (' .. m('album') .. ') (' .. i('filename') .. ')' end The string you enter here will be parsed as a command line before parsing the actual command line parameters. What you enter here will act as a default setting and may or may not be overridden from the 'real' command line. Example: enter '-o alsa -R' below to use ALSA output running realtime as a default. The template string you enter here will be used to construct a single title line from an Artist, a Record and a Track name. These are denoted by %%%%a, %%%%r and %%%%t, respectively. The template string you enter here will be used to construct the filename of the exported files. The Artist, Record and Track names are denoted by %%%%a, %%%%r and %%%%t. The track number and format-dependent file extension are denoted by %%%%n and %%%%x, respectively. The flag %%%%i gives an identifier which is unique within an export session. (%.1f MB) (%d/%d) (capacity = %.1f MB) Free space (%.1f MB) Selected: out L out R% of standard deviation% of standard deviation :%.1f MB / %.1f MB%d / %d directories%d / %d files%d dB%d of %d songs have format unsupported by your player. Do you want to proceed?%d%% L%d%% R%ld Hz(Untitled)(audio only)(choose a category)(error loading image)(no comment)(no description)(no image)(none)*File info*Music Store100 pixels200 pixels300 pixels50 pixelsDevice statusLocal directoryRemote directorySongs infoTransfer progressA large, coloured fishALSA Audio APEAbortAbort ongoing updateAborted...AboutAbstractAccessAction:Active song in playlist: AddAdd ArtistAdd RecordAdd TrackAdd URLAdd all items to playlistAdd all items to playlist (Album mode)Add directoryAdd filesAdd files to playlist (Press right mouse button for menu)Add item...Add mouse button commandAdd new artist to this store...Add new artist...Add new items to playlistAdd new items to playlist (Album mode)Add new record to this artist...Add new record...Add new track to this record...Add new track...Add to CommentsAdd to Music StoreAdd to playlistAdd to playlist (Album mode)Add year to the comments of new recordsAdding files to PlaylistAlbumAlbum Sort OrderAlbum imageAlbum mode is the default when adding entire recordsAlbum:AllAll Audio FilesAll FilesAll Playlist FilesAll tracksAll wordsAlways show the tab barAn error occurred while attempting to connect to the CDDB server.An error occurred while submitting the record to the CDDB server.AppearanceApply averaged RVA to tracks of the same recordAqualung is compiled with system tray support, but the status icon could not be embedded in the notification area. Your desktop may not have support for a system tray, or it has not been configured correctly.Aqualung is compiled without LADSPA plugin support. See the About box and the documentation for details.Aqualung is compiled without Sample Rate Converter support. See the About box and the documentation for details.Aqualung playlist (*.xml)ArtistArtist appears to be in all lowercase. Do you want to proceed?Artist appears to be in all uppercase. Do you want to proceed?Artist nameArtist name (lowercase)Artist namesArtist/Album already existing, not emptyArtist/performerArtist:Ask for confirmation when removing itemsAttached PictureAttached Picture frame with no image set! Please set an image or remove the frame.Audio CDAudio dataAudiophileAuthors:Auto-check interval [hour]:Auto-create tracks from these files:Automatic update has been disabled for all feeds in the Podcasts store popup menu.Automatically add CDs to PlaylistAutomatically remove CDs from PlaylistAutomatically roll to active trackAutomatically update feedsAvailable connectionsAvailable pluginsAvailable skinsAverageBPMBack coverBalance: %sBand/OrchestraBand/artist logotypeBand/orchestraBandwidth:Batch update & encode (mass tagger, CD ripper, file export)Batch-update file metadata...BatteryBeginBibliographyBig timer: Binary ObjectBitrate [kbps]:BrowseBuild / Update store from filesystem...Build version: Build/Update storeBuilding store from filesystemBurn ProofButtonCC2 Error CorrectionCD AudioCD drive speed:CDDA (Audio CD) support CDDBCDDB (not available)CDDB lookupCDDB queryCDDB query for this CD...CDDB query for this record...CDDB server:CDDB support CDDBP (port 888)Calculate RVACalculate volumeCalculate volume (recursive)Calculating volume levelCannot write to selected directory. Please select another directory.CapitalizationCapitalize: Case sensitiveCatalog NumberCategoryCategory:ChangeChange balanceChange current songChange song positionChange volumeChannel count:Channels:Clear connectionsClear listClick here to set mouse buttonCloseClose other tabsClose tabClose trayClose window when completeClose window when transfer completeCollapse all itemsColorsColumnCombine play and pause buttonsCommandCommentCommentsComments:Commercial InformationComposerCompressed modules (*.bz2)Compressed modules (*.gz)Compressed modules (*.gz, *.bz2)Compression level:Compression: Extra HighCompression: FastCompression: HighCompression: InsaneCompression: NormalConductorConnect via HTTP proxyConnecting to CDDB server...Connection timeout [sec]:ContactContent GroupConversion error in field %s: '%s' does not conform to format '%s'!Conversion to target charset failedConvert underscore to spaceCopyCopyrightCopyright/Legal InformationCore design, engineering & programming: Correct existing recordCould not load image from: %sCover artCreate a new directoryCreate directoryCreate empty storeCreate empty store...Create subdirectories for albumsCreate subdirectories for artistsCurrent file: Cut selectedDSPDateDebut AlbumDecoding support:Default cover width:Delete downloaded items from the filesystemDescriptionDescription:DestinationDetect media changeDevice is busy. (Aqualung was unable to claim its interface.)Device is not responding. Try jiggling the handle.Device path:Direct connection to the InternetDirectory '%s' will be removed with its entire contents. Do you want to proceed?Directory drivenDirectory nameDirectory name (lowercase)Directory structureDisable all pluginsDisable control buttons reliefDisable manual ejectDisable skin supportDiscDisc infoDisc info...Discard changesDo not closeDo not exitDo not magnify images with smaller widthDo not reencode files matching wildcard:Do not reencode files already being in the target formatDo nothingDo you want to save store "%s" before removing from Music Store?Do you want to save the store before removing?Don't show cover thumbnail in the main windowDoneDownload directory:Downloading %d/%d (%d%%) ...Drag and drop entries in the list to set the feed order in the Music Store.Drag and drop entries in the list below to set the column order in the Playlist.Drive infoDrive info...Drop statistical aberrations based onDual channelDuration:During performanceDuring recordingEAN/UPCEdit ArtistEdit RecordEdit StoreEdit TrackEdit artist...Edit feedEdit feed settingsEdit item...Edit record...Edit store...Edit track...EjectEmail address for submission:Embed playlist into main windowEmphasis:Emphasis: noneEmphasis: reservedEnable Music Store tree node iconsEnable all pluginsEnable playback RVAEnable rules hintEnable statusbarEnable statusbar in Music StoreEnable statusbar in playlistEnable systrayEnable toolbarEnable toolbar in Music StoreEnable tooltipsEnable tree node iconsEnabledEncoded byEncoding TimeEncoding support:Enqueue playlistErrorError converting field %s to Year: '%s' is not an integer number!Error in format stringError in title format stringExact matches onlyExclude files matching wildcardExpand Stores on startupExpected '}' after '{', but end of string found.Export all items...Export artist...Export filesExport item...Export new items...Export record...Export store...Export track...Exporting filesExtended Title Format Files (*.lua)Extended data:FLAC PicturesFailed to set metadata for the following files:Failed to write metadata to file. Reason: %sFileFile "%s" does not exist or your write permission has been withdrawn. Check if the partition containing the store file has been unmounted.File '%s' will be removed. Do you want to proceed?File OwnerFile TypeFile format:File icon (32x32 PNG)File icon (other)File infoFile info...File is not writableFile name: File:FilenameFilename template:Filename:Files selected for removalFilesystemFilterFirst word onlyFollows the directory structure to identify the artists and records. The files are added on a record basis.FontsForce TOC re-read on every drive scanForce case: Force other letters to lowercaseFormatFormat:Free Lossless Audio Codec (*.flac)Free Lossless Audio Codec (FLAC) Free spaceFrench: Front coverGeneralGeneric StreamMetaGenreGenre:German: Graphics:HTTP (port 80)Hard reset deviceHelpHide AqualungHide comment paneHide the Music Store comment paneHomepage:Horizontal mouse wheel:Hungarian: IDID3v1ID3v2ISBNISRCIcy-DescriptionIcy-GenreIcy-NameIdleIllustrationImplicit command lineImport Comment tagImport Replaygain tag as manual RVAImport as ArtistImport as RVAImport as RecordImport as Sort KeyImport as TitleImport as Track No.Import as YearIn any caseInclude only files matching wildcardIndependentIndexInitial keyInputsInstrumentsInstruments:Internal errorInternetInternet Radio Station NameInternet Radio Station OwnerInterpreted/RemixedIntroplayInvalid 'Genre' field valueInvalid 'Track no.' field valueInvert current stateInvert selectionInvolved PeopleIt is very likely that the year is wrong. Do you want to proceed?Italian: JACK Audio Server JACK Port SetupJACK connection lostJACK has either been shutdown or it disconnected Aqualung because it was not fast enough. All you can do now is restart both JACK and Aqualung.JACK port setupJapanese: Joint stereoKeep main window always on topKey: LADSPA patch builderLADSPA plugin processingLADSPA plugin support LAME (MP3) LAVC (AC3, AAC, WavPack, WMA, etc.) LAVC audio/video filesLabel CodeLanguageLayer ILayer IILayer IIILead artist/performerLeaflet pageLeft and right mouse buttons are reserved.Left buttonLengthLength:LicenseLimitsLinear threshold [dB]Linear threshold [dB] :Listening environment:Living roomLoad playlistLoad playlist in new tabLoad settings from Music Store fileLocal CDDB directory:LocationLocation and filenameLogo, icons: Loop playback support Loop range: %d-%d%%Loop range: %d-%d%% [%s - %s]Lua (programmable title formatting) support Lyricist/Text WriterLyricist/text writerMIME type: %sMOD Audio (MOD, S3M, XM, IT, etc.) MONOMP3 Playlist (*.m3u)MPEG Audio (*.mp3, *.mpa, *.mpega, ...)MPEG Audio (MPEG 1-2.5 Layer I-III) MPEG StreamMetaMain windowMatches:Maximum number of items:Maximum number of retries:Maximum space to use [MB]:MediaMemory allocation errorMetadataMetadata editor (File info dialog)Middle buttonMiscellaneousMode:Model:Module infoModules (*.xm, *.mod, *.it, *.s3m, ...)Monkey's Audio Codec Monkey's Audio Codec (*.ape)MoodMount RainierMouse buttonMouse buttonsMouse wheelMovie/video screen captureMultimedia Playlist (*.pls)Musepack Musepack (*.mpc)Musepack ReplayGainMusic StoreMusic Store Files (*.xml)Music Store: Musician CreditsMuteNULLNameName to sort by:Name transformationName:New tabNextNext songNo discNo matching record found.No metadata support for this formatNo outputNo proxy for:No suitable iRiver iFP device found. Perhaps it is unplugged or turned off.No.Noisy workshopNoneNone of the selected songs has format supported by your player. Do you want to proceed?Note: pre-existing tags will be updated even though they might not be checked here.OSS Audio OfficeOfficial Artist WebsiteOfficial Audio File WebsiteOfficial Audio Source WebsiteOfficial Radio Station WebsiteOgg Speex Ogg Speex (*.spx)Ogg Vorbis Ogg Vorbis (*.ogg)Ogg Xiph CommentsOne or more stores in Music Store have been modified. Do you want to save them before exiting?One song has format unsupported by your player. Do you want to proceed?Only if unmeasuredOpenBSD compatibility, metadata tweaks: Optional features:OrganizationOriginal AlbumOriginal ArtistOriginal FilenameOriginal LyricistOriginal Release TimeOtherOutputOutput driver support:Output:OutputsOverall: Override skin settingsParanoiaParanoia error correctionPart Of A SetPathPaths must either be absolute or starting with a tilde, which will be expanded to the user's home directory. Drag and drop entries in the list to set the store order in the Music Store.Paths must either be absolute or starting with a tilde.Paths to Music Store databasesPatterns:PausePaymentPerform overlapped readsPerformerPerformer Sort OrderPicture type:PlayPlay CD AudioPlay/PausePlay/Pause songPlay/Stop songPlayback RVAPlayback RVA is currently disabled. Do you want to enable it now?PlaylistPlaylist DelayPlaylist column orderPlaylist: Please enter a new name.Please enter directory name.Please select a Music Store database.Please select a Programable Title Format File.Please select a local path.Please select at least one valid song from playlist.Please select the audio file for this track.Please select the audio files for this record.Please select the directory for exported files.Please select the directory for ripped files.Please select the download directory for this podcast.Please select the root directory.Please select the xml file for this store.Please specify the file to load the image from.Please specify the file to load the playlist from.Please specify the file to save the image to.Please specify the file to save the playlist to.Podcast URL:Podcast support PodcastsPort:Position: %d%%Post Fader (after Volume & Balance)Pre Fader (before Volume & Balance)Predefined transformationsPreviousPrevious songProcessing metadataProcessing:ProducedProfile: BraindeadProfile: InsaneProfile: RadioProfile: StandardProfile: TelephoneProfile: ThumbProfile: XtremeProgrammable title format fileProgramming, GUI engineering: ProgressProgress:Protocol for querying (direct connection only):Proxy host:Proxy settingsPublication RightPublisherPublisher's Official WebsitePublisher/studio logotypePulseAudio Put control buttons at the bottom of playlistQuitRVARVA for Unmeasured Files [dB] :RVA valuesRead CD+GRead CD-DARead CD-RRead CD-RWRead DVD+RRead DVD+RWRead DVD-RRead DVD-RAMRead DVD-ROMRead DVD-RWRead ISRCRead MCNRead Mode 2 Form 1Read Mode 2 Form 2Read multiple sessionsReadingReading fileReally remove "%s" from the Music Store?Really remove '%s' from the Music Store?Really remove store "%s" from the Music Store?ReasonRecordRecord DateRecord LocationRecord nameRecord name (lowercase)Record titlesRecording location/studioRecursive search from the root directory for audio files. The files are processed independently, so only metadata and filename transformation are available.Reference volume [dBFS] :RefreshRegexp matches empty stringRegexp:Regular expressionRelatedRelease TimeRemoveRemove ArtistRemove RecordRemove StoreRemove TrackRemove allRemove artistRemove deadRemove feedRemove file extensionRemove filesRemove item...Remove leading numberRemove non-existing files from storeRemove older items [day]:Remove recordRemove selectedRemove selected songs from playlist (Press right mouse button for menu)Remove storeRemove trackRemoving non-existing filesRenameRename playlistReorder feedsRepeat all songsRepeat current songReplace:ReplayGain Album GainReplayGain Album PeakReplayGain Reference LoudnessReplayGain Track GainReplayGain Track PeakReplayGain tag to use (with fallback to the other): Replaygain_album_gainReplaygain_track_gainReread data for existing tracksReread file metadataRescanResumeRetrieving matches from server...Revision:Right buttonRipRip CDRip CD...Ripping CD tracksRoll to active songRoot path:Running pluginsRussian: SRC Type: STEREOSTOPPINGSample Rate Converter support Sample Rate Converter typeSamplerate:SamplesSamples:SandboxSaveSave all playlistsSave all storesSave and closeSave and restore the playlist on exit/startupSave playlistSave playlist periodically [min]:Save storeScanning filesSearchSearch in:Search the Music StoreSearch the PlaylistSearch...SelectSelect a font...Select allSelect all songs in playlist (Press right mouse button for menu)Select build typeSelect directorySelect filesSelect first and close windowSelect juke-box discSelect noneSelected files:Send to iFP deviceSeparateSet SubtitleSet drive speedSettingsShow AqualungShow RVA valuesShow active track name in boldShow close button in tabShow cover thumbnail for Music Store tracks onlyShow hidden files and directories in file choosersShow song name in the main window's titleShow soundfile size in statusbarShow tags tab first in the file info dialogShow track lengthsShuffle songsSimple view in LADSPA patch builderSingle channelSizeSkin chooserSkin support, look & feel, GUI hacks: Small timers: SoftwareSong in playlist: Song info: Song title: Sort artists bySort records bySound Files (*.wav, *.aiff, *.au, ...)SourceSource file:Start minimizedStatusbar: Steepness [dB/dB] :StereoStopStop adding filesStop adding songsStructure:Subdirectory name length limit:Submit CD to CDDB database...Submit new recordSubmit record to CDDB database...Subscribe to new feedSubtitleSuccessSwedish: SystraySystray support Tag files with metadataTagging TimeTags to add when creating or updating MPEG audio files:Target directory for ripped filesTarget directory:Target file:TestThe email address provided for submission is invalid.The information below is reported by the drive, and may not reflect the actual capabilities of the device.The selected files will be deleted from the filesystem. No recovery will be possible after this operation. Do you want to proceed?The selected song has format unsupported by your player. Do you want to proceed?The specified store has already been added to the list.The store '%s' already exists. Add it on the Settings/Music Store tab.There are unsaved changes to the file metadata.This Aqualung binary is compiled with:This CD does not contain CD-Text information.This button is already assigned.This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.Timeout for socket I/O:TitleTitle FormatTitle Sort OrderTitle appears to be in all lowercase. Do you want to proceed?Title appears to be in all uppercase. Do you want to proceed?Title:Toggle LADSPA patch builderToggle music storeToggle playlistTotalTotal samples:Total: TrackTrack No.Track commentTrack lengthsTrack nameTrack numberTrack titlesTrack:TracksTranslators:Trim leading, tailing and duplicate spacesType:URL:Ukrainian: Unable to open fileUnable to remove %d file.Unable to remove %d files.Undo close tabUnexpected end of string after '?'.United windows minimizationUnknownUnknown AlbumUnknown ArtistUnknown RecordUnknown TrackUnknown conversion type character found after '%%%%'.Unknown conversion type character found after '?'.Unknown discUnknown errorUnlimited retry on failed reads (never skip)UnmeasuredUnmeasured tracks onlyUnrecognizedUntitledUpdate all feedsUpdate feedUpdate file metadataUpdate file metadata...Updating...Use basename only instead of full path if no metadata is available.Use manual RVA value [dB]Use relative paths in store fileUse the local database onlyUser Defined TextUser Defined URLVBR encodingVendorVendor:Verify data integrityVersionVertical mouse wheel:Visible name:Volume level:Volume: %sWarn me if the Window Manager does not support system trayWarningWavPack WavPack (*.wv)When adding new frames, try to set their contents from another tag's equivalent frame.When shuffling, records added in Album mode are played in orderWin32 Sound API Write CD-RWrite CD-RWWrite DVD+RWrite DVD+RWWrite DVD-RWrite DVD-RAMWrite DVD-RWWritingYearYear:You have to provide an email address for CDDB submission.You will need to restart Aqualung for the following changes to take effect:_Abort_Add files..._Browse..._Configure_Download_Uploadartistartistsbestbit doublebit floatbit signedbit unsignedcounting...daydaysdrivedrivesencodingfastfeedfeedsfield:iFP device manager (download mode)iFP device manager (upload mode)iRiver iFP driver support itemitemsnew itemnew itemsrrecordrecordsroot / artist / artist / artist / record / trackroot / artist / artist / record / trackroot / artist / record / trackroot / record / trackrwsecondssndfile (WAV) sndfile (WAV, AIFF, etc.) sndio Audio tag:tracktracksunreachableuse browser window widthProject-Id-Version: Report-Msgid-Bugs-To: POT-Creation-Date: 2010-01-13 00:15+0100 PO-Revision-Date: 2010-01-13 00:16+0100 Last-Translator: Wolfgang Stoeggl Language-Team: German MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n != 1); X-Poedit-Language: German Maximale Anzahl der Wiederholungen: Kein Lese-/Schreibzugriff auf den Zielordner! Hier sollten Sie eine mit Komma getrennte Liste von Domänen eingeben, die ohne die Benutzung des oben eingestellten Proxy-Servers angesprochen werden sollen. Beispiele: localhost, .localdomain, .my.domain.com Die meisten Laufwerke benachrichtigen Aqualung, wenn eine CD eingelegt oder ausgeworfen worden ist. Jedoch trifft das nicht auf alle Laufwerke zu, weshalb eine neu eingelegte CD möglicherweise nicht von Aqualung wahrgenommen wird. In solchen Fällen sollte das Aktivieren dieser Option Abhilfe schaffen. Einstellung der Laufwerksgeschwindigkeit für das Abspielen von CDs in CD-ROM Geschwindigkeits-Einheiten. Eine Geschwindigkeitseinheit entspricht einer Rohdaten-Lesegeschwindigkeit von 176 kBps. Warnung: Nicht alle Laufwerke beachten diese Einstellung. Weniger Geschwindigkeit bedeutet üblicherweise weniger Laufwerkslärm. Wenn Sie jedoch den »Paranoia«-Fehlerkorrektur-Modus verwenden, werden üblicherweise höhere Geschwindigkeiten benötigt, um leere Puffer und damit hörbare Aussetzer zu vermeiden. Bitte nehmen Sie zur Kenntnis, dass diese Einstellungen nicht das Auslesen von CDs betreffen, welches immer bei maximaler Geschwindigkeit und händisch gesetzten Fehlerkorrekturmodi ausgeführt wird. Die gewählte Musiksammlung hat bereits einen entsprechenden Interpreten und ein Album, das bereits Titel enthält. Wenn Sie OK drücken werden diese Titel entfernt. Die Dateien bleiben intakt, aber sie werden von der Ziel-Musiksammlung entfernt. Drücken Sie Abbrechen, um Interpret/Album zu ändern oder zur Ziel-Musiksammlung zurückzukehren. Die Datei, die Sie hier eingeben oder auswählen, wird von Lua verwendet, um den Titel zu formatieren. Weitere Details findet man im Aqualung-Handbuch. Hier ist ein kurzes Beispiel dafür, was in der Datei verwendet werden kann: function playlist_title() return m('artist') .. '-' .. m('title') .. ' (' .. m('album') .. ') (' .. i('filename') .. ')' end Diese Zeichenkette wird als eine Befehlszeile geparst, bevor die eigentlichen Befehlszeilen-Parameter geparst werden. Was Sie hier schreiben wird als Voreinstellung fungieren und kann durch die »echte« Befehlszeile überschrieben werden. Beispiel: Eingabe von '-o alsa -R' um die ALSA-Ausgabe in Echtzeit als eine Voreinstellung zu benutzen. Diese Zeichenketten-Maske wird für die Konstruktion einer Titelzeile aus einem Interpreten, einem Album und einem Titel benutzt. Diese werden mit %%%%a, %%%%r und %%%%t bezeichnet. Diese Vorlage-Zeichenkette wird für die Konstruktion eines Dateinamens für die zu exportierenden Dateien benutzt. Interpret, Album und Titelnamen werden mit %%%%a, %%%%r und %%%%t bezeichnet. Die Titelnummer und formatabhängige Dateiendung werden mit %%%%n und %%%%x bezeichnet. Das Flag %%%%i ist eine Bezeichnung, die innerhalb einer Exportsitzung einmalig ist. (%.1f MB) (%d/%d) (Kapazität = %.1f MB) Freier Speicherplatz (%.1f MB) Ausgewählt: Ausgang L Ausgang R% der Standardabweichung% der Standardabweichung :%.1f MB / %.1f MB%d / %d Ordner%d / %d Dateien%d dB%d von %d Titeln haben ein Format, das von Aqualung nicht unterstützt wird. Möchten Sie fortfahren?%d%% L%d%% R%ld Hz(Unbetitelt)(nur Audio)(Wählen Sie eine Kategorie)(Fehler beim Laden des Bildes)(kein Kommentar)(Keine Beschreibung)(kein Bild)(keine)*Datei-Info*Musiksammlung100 Pixel200 Pixel300 Pixel50 PixelGerätestatusLokaler OrdnerEntfernt liegender OrdnerTitelinformationenÜbertragungsfortschrittEin großer, farbiger FischALSA Audio APEAbbrechenLaufende Aktualisierung abbrechenAbgebrochen …Über AqualungZusammenfassungZugriffAktion:Aktiver Titel in der Playliste: HinzufügenInterpreten hinzufügenAlbum hinzufügenTitel hinzufügenAdresse hinzufügenAlle Elemente zur Playliste hinzufügenAlle Elemente zur Playliste hinzufügen (Album-Modus)Ordner hinzufügenDateien hinzufügenDateien zur Playliste hinzufügen (Drücken Sie die rechte Maustaste für das Menü)Element hinzufügen …Befehl zum Hinzufügen von MaustastenNeuen Interpreten zu dieser Sammlung hinzufügen …Neuen Interpreten hinzufügen …Neue Elemente zur Playliste hinzufügenNeue Elemente zur Playliste hinzufügen (Album-Modus)Neues Album zu diesem Interpreten hinzufügen …Neues Album hinzufügen …Neuen Titel zu diesem Album hinzufügen …Neuen Titel hinzufügen …Zu den Kommentaren hinzufügenZur Musiksammlung hinzufügenZur Playliste hinzufügenZur Playliste hinzufügen (Album-Modus)Jahr zu den Kommentaren neuer Alben hinzufügenDateien werden zur Playliste hinzugefügtAlbumText für AlbensortierungAlbumbildAlbum-Modus ist die Vorgabe, wenn ein gesamtes Album hinzugefügt wirdAlbum:AlleAlle AudiodateienAlle DateienAlle Playlisten-DateienAlle TitelAlle WörterReiterleiste immer anzeigenWährend des Versuchs zum CDDB-Server zu verbinden trat ein Fehler auf.Während der Übertragung des Albums zum CDDB-Server trat ein Fehler auf.AussehenDurchschnittliches RVA auf alle Titel eines Albums anwendenAqualung wurde mit Kontrollleisten-Unterstützung kompiliert, aber das Statussymbol konnte nicht in die Kontrollleiste eingebettet werden. Ihre Benutzeroberfläche unterstützt möglicherweise keine Kontrollleiste oder sie wurde nicht richtig konfiguriert.Aqualung wurde ohne LADSPA-Plugin-Unterstützung kompiliert. Details findet man in der »Über Aqualung«-Box und in der Dokumentation.Aqualung wurde ohne Samplerate-Konverterunterstützung kompiliert. Details findet man in der »Über Aqualung«-Box und in der Dokumentation.Aqualung-Playliste (*.xml)InterpretDer Name des Interpreten scheint in Kleinbuchstaben zu sein. Möchten Sie fortsetzen?Der Name des Interpreten scheint in Großbuchstaben zu sein. Möchten Sie fortsetzen?Name des InterpretenName des Interpreten (Kleinbuchstaben)Namen des InterpretenInterpret/Album existiert bereits und ist nicht leerInterpretInterpret:Frage nach Bestätigung beim Entfernen von ElementenAngefügtes BildAngehängter Bilderrahmen enthält kein Bild! Bitte fügen Sie ein Bild ein oder entferne Sie den Rahmen.Audio-CDAudio-DatenAudiophilAutoren:Automatisches Abfrageintervall [Stunden]:Titel automatisch aus diesen Dateien erstellen:Automatische Aktualisierung wurde für alle Feeds im Musiksammlungs-Podcast-Menü deaktiviert.CDs automatisch zur Playliste hinzufügenCDs automatisch von der Playliste entfernenAutomatisch zum aktiven Titel rollenFeeds automatisch aktualisierenVerfügbare VerbindungenVerfügbare PluginsVerfügbare OberflächenDurchschnittBPMCover-RückseiteBalance: %sBand/OrchesterSchriftzug Band/InterpretBand/OrchesterBandbreite:Stapelweise aktualisieren und kodieren (Mass-Tagger, CD-Ausleser, Dateiexport)Datei-Metadaten stapelweise aktualisieren …BatterieAnfangBibliographieGroße Zeitanzeige: Binäres ObjektBitrate [kbps]:DurchsuchenErstellen / Aktualisieren der Sammlung vom Dateisystem …Version: Sammlung Erstellen/AktualisierenErstellen der Sammlung anhand der OrdnerstrukturBurn-ProofTasteCC2 FehlerkorrekturCD-AudioCD-LaufwerksgeschwindigkeitCDDA (Audio CD) Unterstützung CDDBCDDB (nicht verfügbar)Schlage in CDDB nachCDDB-AbfrageCDDB-Abfrage für diese CD …CDDB-Abfrage für dieses Album …CDDB-Server:CDDB-Unterstützung CDDBP (Port 888)RVA messenLautstärke messenLautstärke messen (rekursiv)Lautstärke wird gemessenKann im ausgewählten Ordner nicht schreiben. Bitte wählen Sie einen anderen.GroßschreibungGroß schreiben:Groß-/Kleinschreibung unterscheidenKatalognummerKategorieKategorie:ÄndernBalance einstellenDerzeitigen Titel ändernPosition im Titel ändernLautstärke regelnKanalanzahl:Kanäle:Verbindungen aufhebenListe löschenKlicken Sie hier, um die Maustasten festzulegenSchließenAlle anderen Reiter schließenReiter schließenLade schließenFenster nach Beendigung schließenFenster nach vollständiger Übertragung schließenAlle Elemente einklappenFarbenSpalteWiedergabe- und Pausenknopf vereinigenBefehlKommentarKommentareKommentare:Kommerzielle InformationKomponistKomprimierte Module (*.bz2)Komprimierte Module (*.gz)Komprimierte Module (*.gz, *.bz2)Kompressionsgrad:Kompression: Extra HochKompression: SchnellKompression: HochKompression: WahnsinnigKompression: NormalDirigentVerbinde über HTTP-ProxyVerbinde zum CDDB-Server …Verbindungs-Zeitüberschreitung [Sek.]:KontaktInhaltsgruppeUmwandlungsfehler im Feld %s: '%s' stimmt nicht mit '%s' überein!Konvertierung zur Ziel-Charakterkodierung fehlgeschlagenUnterstrich zu Leerzeichen umwandelnKopieUrheberrechtUrheberrechtliche/Gesetzliche InformationKernentwurf, technische Planung & Programmierung: Bestehenden Eintrag korrigierenKonnte Bild von folgender Stelle nicht laden: %sCoversNeuen Ordner anlegenOrdner anlegenLeere Sammlung erzeugenLeere Sammlung anlegen …Unterordner für Alben anlegenUnterordner für Interpreten anlegenDerzeitige Datei:Ausgewählte freistellenDSPDatumDebutalbumDekodierbare Dateiformate:Standard-Coverbreite:Heruntergeladene Elemente aus dem Dateisystem löschenBeschreibungBeschreibung:ZielDatenträgerwechsel erkennenGerät ist beschäftigt. (Aqualung war es nicht möglich, das Gerät anzusprechen)Gerät reagiert nicht. Bitte Überprüfen Sie den Anschluss des Gerätes.Gerätepfad:Direkte Verbindung zum InternetOrdner '%s' wird mit seinem gesamten Inhalt entfernt. Möchten Sie fortfahren?VerzeichnisorientiertOrdnernameOrdnername (Kleinbuchstaben)OrdnerstrukturAlle Plugins deaktivierenRelief bei Kontrollknöpfen deaktivierenManuelles Auswerfen deaktivierenOberflächen-Unterstützung deaktivierenMediumCD-InfoCD-Info …Änderungen verwerfenNicht schließenNicht beendenBilder mit geringerer Breite nicht vergrößernDateien nicht neu kodieren, die der Maske entsprechen:Dateien, die bereits im Zielformat sind, nicht neu kodierenNichts unternehmenMöchten Sie die Sammlung "%s" speichern, bevor sie aus der Musiksammlung entfernt wird?Möchten Sie die Sammlung vor dem Entfernen speichern?Miniatur-Coverbild nicht im Hauptfenster anzeigenFertigOrdner zum Herunterladen:Herunterladen %d/%d (%d%%) …Ziehen Sie die Einträge in der Liste, um die Reihenfolge der Feeds in der Musiksammlung zu ändern.Ziehen Sie die Einträge in der nachstehenden Liste, um die Reihenfolge der Spalten in der Playliste zu ändern.Laufwerks-InfoLaufwerks-Info …Verringerung der statistischen Abweichung basierend aufZweikanalZeitdauer:Während der AufführungWährend der AufnahmeEAN/UPCInterpret bearbeitenAlbum bearbeitenSammlung bearbeitenTitel bearbeitenInterpreten bearbeiten …Feed bearbeitenFeed-Einstellungen bearbeitenElement bearbeiten …Album bearbeiten …Sammlung bearbeiten …Titel bearbeiten …AuswerfenE-Mail-Adresse für die Übertragung:Playliste ins Hauptfenster einbettenBetonung:Betonung: keineBetonung: reserviertBaumknoten-Symbole in der Musiksammlung aktivierenAlle Plugins aktivierenAktiviere Wiedergabe-RVARegelhinweise anzeigenStatusleiste aktivierenStatusleiste in der Musiksammlung aktivierenStatusleiste in der Playliste aktivierenKontrollleistensymbol aktivierenWerkzeugleiste aktivierenWerkzeugleiste in der Musiksammlung aktivierenMinihilfen einschaltenBaumknoten-Symbole aktivierenAktivKodiert vonKodierungszeitKodierbare Dateiformate:Playliste einreihenFehlerFehler beim Umwandeln des Feldes %s zum Jahr: '%s' ist keine ganze Zahl!Fehler in der Formatierungs-ZeichenketteFehler in der Titelformat-ZeichenketteNur genaue TrefferDateien, die der Maske entsprechen, ausschließenSammlungen beim Start ausklappenEs wurde '}' nach '{' erwartet, aber das Ende der Zeichenkette gefunden.Alle Elemente exportieren …Interpreten exportieren …Dateien exportierenElement exportieren …Neue Elemente exportieren …Album exportieren …Sammlung exportieren …Titel exportieren …Dateien werden exportiertErweiterte Titelformatdateien (*.lua)Erweiterte Daten:FLAC-BilderDas Schreiben von Metadaten schlug bei folgenden Dateien fehl:Das Schreiben von Metadaten schlug fehl. Grund: %sDateiDatei »%s« nicht vorhanden oder Sie haben keine Schreibberechtigung. Prüfen Sie, ob die Partition mit der Musiksammlungsdatei ausgehängt worden ist.Datei '%s' wird entfernt. Möchten Sie fortfahren?DateieigentümerDateitypDateiformat:Dateisymbol (32x32 PNG)Dateisymbol (andere)Datei-InfoDatei-Info …Datei ist nicht beschreibbarDateiname:Datei:DateinameDateinamen-Vorlage:Dateiname:Zum Entfernen ausgewählte DateienDateisystemFilterNur das erste WortFolgt der Ordnerstruktur, um Interpreten und Alben zu ermitteln. Die Dateien werden auf Basis der Alben hinzugefügt.SchriftartenNochmaliges TOC-Lesen bei jeder Laufwerksabfrage erzwingenSchreibweise erzwingen: Kleinschreibung für alle anderen Buchstaben erzwingenFormatFormat:Free Lossless Audio Codec (*.flac)Free Lossless Audio Codec (FLAC) Freier SpeicherplatzFranzösisch: Cover-VorderseiteAllgemeinGeneric-StreamMetaGenreGenre:Deutsch: Graphiken:HTTP (Port 80)Gerät hart zurücksetzenHilfeAqualung verbergenKommentarausschnitt verbergenMusiksammlungs-Kommentarausschnitt verbergenWebseite:Horizontales Mausrad:Ungarisch: IDID3v1ID3v2ISBNISRCIcy-BeschreibungIcy-GenreIcy-NameLeerlaufIllustrationImplizite BefehlszeileKommentar-Tag importierenReplaygain-Tag als manuelles RVA importierenAls Interpret importierenAls RVA importierenAls Album importierenAls Sortierschlüssel importierenAls Titel importierenAls Titelnummer importierenAls Jahr importierenIn jedem FallNur Dateien, die der Maske entsprechen, berücksichtigenUnabhängigIndexGrundtonEingängeInstrumenteInstrumente:Interner FehlerInternetName der InternetradiostationBesitzer der InternetradiostationInterpretiert/neu gemischtIntroplayUngültiger Wert im Feld »Genre«Ungültiger Wert im Feld »Titelnummer«Derzeitigen Zustand umkehrenAuswahl umkehrenBeteiligte PersonenEs ist sehr wahrscheinlich, dass das Jahr falsch ist. Möchten Sie fortsetzen?Italienisch: JACK Audio Server JACK-Verbindung einrichtenJACK-Verbindung verlorenJACK wurde entweder beendet oder es hat Aqualung abgekoppelt weil Aqualung nicht schnell genug war. JACK und Aqualung sollten neu gestartet werden.JACK-Verbindung einrichtenJapanisch: Verbundenes StereoHauptfenster immer im Vordergrund behaltenSchlüssel: LADSPA-SchaltkastenLADSPA-Plugin-VerarbeitungLADSPA-Plugin-Unterstützung LAME (MP3) LAVC (AC3, AAC, WavPack, WMA, etc.) LAVC-Audio/Video-DateienLabel-CodeSpracheSchicht ISchicht IISchicht IIIHauptinterpretFaltblattLinke und rechte Maustaste sind reserviert.Linke TasteLängeLänge:LizenzBegrenzungenLinearschwelle [dB]Linearschwelle [dB] :Hörumgebung:WohnzimmerPlayliste ladenPlayliste in neuem Reiter ladenEinstellungen aus der Musiksammlungsdatei ladenLokales CDDB-Verzeichnis:OrtOrt und DateinameLogo, Symbole: Schleifenwiedergabe Schleifenlänge: %d-%d%%Schleifenlänge: %d-%d%% [%s - %s]Lua-Unterstützung (programmierbare Titelformatierung) Lyriker/TexterLyriker/TexterMIME-Typ: %sMOD Audio (MOD, S3M, XM, IT, etc.) MONOMP3-Playliste (*.m3u)MPEG Audio (*.mp3, *.mpa, *.mpega, …)MPEG Audio (MPEG 1-2.5 Layer I-III) MPEG-StreamMetaHauptfensterTreffer:Maximale Anzahl an Elementen:Maximale Anzahl der Wiederholungen:Maximaler Platzverbrauch [MB]:MedientypSpeicherzuordnungsfehlerMetadatenMetadaten-Editor (Dateiinformationsdialog)Mittlere TasteSonstigesModus:Modell:Modul-InfoModule (*.xm, *.mod, *.it, *.s3m, …)Monkey's Audio Codec Monkey's Audio Codec (*.ape)StimmungMount-RainierMaustasteMaustastenMausradFilm/Video AufzeichnungMultimedia-Playliste (*.pls)Musepack Musepack (*.mpc)Musepack-ReplayGainMusiksammlungMusiksammlungsdateien (*.xml)Musiksammlung: Mitwirkende MusikerStummNULLNameNach folgendem Namen sortieren:NamensumwandlungName:Neuer ReiterNächsterNächster TitelKeine CDKein passendes Album gefunden.Keine Metadatenunterstützung für dieses FormatKeine AusgabeKein Proxy für:Kein passendes iRiver-iFP-Gerät gefunden. Möglicherweise ist es ausgesteckt oder ausgeschalten.Nr.Laute WerkstattKeineKeiner der ausgewählten Titel hat ein Format, das von Aqualung unterstützt wird. Möchten Sie fortfahren?Hinweis: Bereits existierende Tags werden aktualisiert, auch wenn sie hier nicht ausgewählt sind.OSS Audio BüroOffizielle Webseite des InterpretenOffizielle Audiodatei-WebseiteOffizielle Audioquellen-WebseiteOffizielle Radiostations-WebseiteOgg Speex Ogg Speex (*.spx)Ogg Vorbis Ogg Vorbis (*.ogg)Ogg-Xiph-KommentareEine oder mehrere Sammlungen in der Musiksammlung wurden verändert. Möchten Sie diese vor dem Beenden speichern?Ein Titel hat ein Format, das von Aqualung nicht unterstützt wird. Möchten Sie fortfahren?Nur wenn ungemessenOpenBSD-Kompatibilität, Metadaten-Kniffe: Optionale Funktionen:OrganisationOriginalaufnahmeOriginalinterpretOriginaler DateinameOriginaltexterVeröffentlichungszeitpunkt des OriginalsAndereAusgabeUnterstützte Ausgabemethoden:Ausgabe:AusgängeInsgesamt:Oberflächen-Einstellungen überschreibenParanoiaParanoia-FehlerkorrekturTeil der SeriePfadPfade müssen entweder absolut sein oder mit einer Tilde beginnen, welche zum persönlichen Ordner des Benutzers erweitert wird. Ziehen Sie die Einträge in der Liste, um die Reihenfolge der Sammlungen in der Musiksammlung zu verändern.Pfade müssen absolut sein oder mit einer Tilde beginnen.Pfade zu den MusiksammlungsdatenbankenMuster:PauseBezahlungÜberlappend auslesenInterpretText für InterpretensortierungBildtyp:WiedergabeAudio-CD abspielenWiedergabe/PauseTitel wiedergeben/pausierenTitel wiedergeben/stoppenWiedergabe-RVAWiedergabe-RVA ist derzeit deaktiviert. Möchten Sie es jetzt aktivieren?PlaylistePlaylisten-VerzögerungReihenfolge der Spalten in der PlaylistePlayliste: Bitte geben Sie einen neuen Namen einBitte geben Sie einen Ordnernamen einBitte wähle Sie eine Musiksammlungsdatenbank.Bitte wählen Sie eine programmierbare Titelformatdatei.Bitte wählen Sie einen lokalen Pfad.Bitte wählen Sie mindestens einen gültigen Titel aus der Playliste.Bitte wählen Sie die Audio Datei für dieses Lied aus.Bitte wählen Sie die Audiodateien für dieses Album aus.Bitte wählen Sie einen Ordner für die exportierten Dateien aus.Bitte wählen Sie einen Order für die eingelesenen Dateien aus.Bitte wählen Sie einen Ordner zum Speichern dieses Podcasts aus.Bitte wählen Sie das Wurzelverzeichnis.Bitte wählen Sie die xml-Datei für diese Sammlung aus.Bitte geben Sie die Datei an, aus der das Bild geladen werden soll.Bitte geben Sie die Datei an, aus der die Playliste geladen werden soll.Bitte geben Sie die Datei an, in der das Bild gespeichert werden sollBitte geben Sie die Datei an, in die die Playliste gespeichert werden soll.Podcast-Adresse:Podcast PodcastsPort:Position: %d%%Post-Fader (nach Lautstärke & Balance)Pre-Fader (vor Lautstärke & Balance)Vordefinierte UmwandlungenVorherigerVorheriger TitelVerarbeite MetadatenVerarbeitung:ProduziertProfil: HirntotProfil: WahnsinnigProfil: RadioProfil: StandardProfil: TelephonProfil: DaumenProfil: ExtremProgrammierbare TitelformatdateiProgrammierung, GUI-Planung: FortschrittFortschritt:Protokoll für die Abfrage (nur bei direkter Verbindung):Proxy-Rechner:Proxy-EinstellungenVeröffentlichungsrechtHerausgeberOffizielle Herausgeber-WebseiteSchriftzug Herausgeber/StudioPulseAudio Kontrollknöpfe unten an der Playliste platzierenBeendenRVARVA für ungemessene Dateien [dB] :RVA-WerteCD+G lesenCD-DA lesenCD-R lesenCD-RW lesenDVD+R lesenDVD+RW lesenDVD-R lesenDVD-RAM lesenDVD-ROM lesenDVD-RW lesenISRC lesenMCN lesenLesemodus 2 Form 1Lesemodus 2 Form 2Mehrere Sitzungen lesenLesenDatei wird gelesenWirklich "%s" aus der Musiksammlung entfernen?Wirklich '%s' aus der Musiksammlung entfernen?Sammlung "%s" wirklich aus der Musiksammlung entfernen?GrundAlbumAufnahmedatumAufnahmeort/StudioName des AlbumsName des Albums (Kleinbuchstaben)AlbentitelAufnahmeort/StudioRekursive Suche vom Wurzelverzeichnis aus nach Audiodateien. Die Dateien werden unabhängig verarbeitet, weshalb nur Metadaten- und Dateinamen-Umwandlung verfügbar sind.Referenzlautstärke [dBFS] :AktualisierenRegulärer Ausdruck entspricht leerer ZeichenketteRegulärer Ausdruck:Regulärer AusdruckVerwandtVeröffentlichungszeitpunktEntfernenInterpret entfernenAlbum entfernenSammlung entfernenTitel entfernenAlle entfernenInterpreten entfernenTote Einträge entfernenFeed entfernenDateiendung entfernenDateien entfernenElement entfernen …Nummer vom Anfang entfernenNicht vorhandene Dateien aus der Musiksammlung entfernenEntferne ältere Elemente [Tage]:Album entfernenAuswahl entfernenMarkierte Titel von der Playliste entfernen (Drücken Sie die rechte Maustaste für das Menü)Sammlung entfernenTitel entfernenEntferne nicht vorhandene DateienUmbenennenPlayliste umbenennenFeeds neu ordnenAlle Titel wiederholenDerzeitigen Titel wiederholenErsetzen:ReplayGain-Album-GainReplayGain-Album-PeakReplayGain-ReferenzlautstärkeReplayGain-Track-GainReplayGain-Track-PeakFolgendes ReplayGain-Tag benutzen (mit Rückfall zum anderen): Replaygain_album_gainReplaygain_track_gainDaten für die vorhandenen Titel erneut lesenDatei-Metadaten erneut einlesenErneut abfragenFortsetzenEmpfange Treffer vom Server …Revision:Rechte TasteAuslesenCD auslesenCD auslesen …CD-Titel auslesenZum derzeitigen Titel rollenWurzelverzeichnis:Laufende PluginsRussisch: SRC-Typ: STEREOWird GESTOPPTAbtastraten-Umwandler Samplerate-KonvertertypSamplerate:SamplesSamples:SandkisteSpeichernAlle Playlisten speichernAlle Sammlungen speichernSpeichern und schließenPlayliste beim Beenden/Starten speichern und ladenPlayliste speichernPlayliste in periodischen Zeitabständen speichern [min]:Sammlung speichernDateien werden gelesenSuchenSuchen in:Musiksammlung durchsuchenPlayliste durchsuchenSuchen …WählenSchriftart wählen …Alles auswählenAlle Titel in der Playliste auswählen (Drücken Sie die rechte Maustaste für das Menü)Wählen Sie die ErstellungsmethodeOrdner wählenDateien wählenWähle ersten Treffer und schließe FensterMusikbox-CD wählenNichts auswählenAusgewählte Dateien:An iFP-Gerät sendenEinzelnUntertitel setzenLaufwerksgeschwindigkeit setzenEinstellungenAqualung zeigenRVA-Werte anzeigenNamen des aktiven Titels fett anzeigenSchließknopf im Reiter anzeigenMiniatur-Coverbild nur für Titel aus der Musiksammlung zeigenVersteckte Dateien und Ordner in der Dateiauswahl anzeigenTitelnamen im Titel des Hauptfensters zeigenGröße der Datei in der Statusleiste anzeigenTag-Reiter als ersten im Dateiinformationsdialog anzeigenTitellängen anzeigenZufällige WiedergabeEinfache Ansicht beim LADSPA-SchaltkastenEinkanalGrößeOberflächenauswahlOberfläche, Aussehen, Handhabung: Kleine Zeitanzeigen: SoftwareTitel in der Playliste: Titelinformation: Titel: Interpreten sortieren nachAlben sortieren nachAudiodateien (*.wav, *.aiff, *.au, …)QuelleQuelldatei:Minimiert startenStatusleiste: Steilheit [dB/dB] :StereoStopHinzufügen von Dateien stoppenHinzufügen von Titeln stoppenStruktur:Unterordnernamen- Längenbeschränkung:CD zur CDDB-Datenbank übertragen …Neuen Eintrag hinzufügenAlbum zur CDDB-Datenbank übertragen …Neuen Feed abonnierenUntertitelErfolgreichSchwedisch: KontrollleisteKontrollleistensymbol Dateien mit Metadaten taggenTagging-ZeitpunktTags, die beim Erstellen oder Aktualisieren von MPEG-Audiodateien hinzugefügt werden sollen:Zielordner für die ausgelesenen DateienZielordnerZieldatei:TestDie für die Übertragung eingegebene E-Mail-Adresse ist ungültig.Die nachfolgenden Informationen wurden vom Gerät geliefert und entsprechen möglicherweise nicht seinen tatsächlichen Fähigkeiten.Die ausgewählten Dateien werden aus dem Dateisystem entfernt. Wiederherstellen wird nach dieser Operation nicht möglich sein. Möchten Sie fortfahren?Der ausgewählte Titel hat ein Format, das von Aqualung nicht unterstützt wird. Möchten Sie fortfahren?Die angegebene Sammlung wurde bereits zur Liste hinzugefügt.Die Sammlung '%s' existiert bereits. Fügen Sie sie am Reiter Einstellungen/Musiksammlung hinzu.Es existieren ungespeicherte Veränderungen an den Datei-Metadaten.Diese Aqualung-Binärdatei wurde kompiliert mit:Diese CD beinhaltet keine CD-Text Information.Diese Taste ist bereits belegt.Dieses Programm ist freie Software. Sie können es unter den Bedingungen der GNU General Public License, wie von der Free Software Foundation herausgegeben, weitergeben und/oder modifizieren, entweder gemäß Version 2 der Lizenz oder (nach Ihrer Wahl) jeder späteren Version. Die Veröffentlichung dieses Programms erfolgt in der Hoffnung, dass es Ihnen von Nutzen sein wird, aber OHNE JEDE GEWÄHRLEISTUNG, sogar ohne die implizite Gewährleistung der MARKTREIFE oder der EIGNUNG FÜR EINEN BESTIMMTEN ZWECK. Details finden Sie in der GNU General Public License. Sie sollten ein Exemplar der GNU General Public License zusammen mit diesem Programm erhalten haben. Falls nicht, schreiben Sie an die Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.Zeitüberschreitung für Sockel I/O:TitelTitelformatText für TitelsortierungDer Titel scheint in Kleinbuchstaben zu sein. Möchten Sie fortsetzen?Der Titel scheint in Großbuchstaben zu sein. Möchten Sie fortsetzen?Titel:LADSPA-Schaltkasten ein-/ausblendenMusiksammlung ein-/ausblendenPlayliste ein-/ausblendenGesamtSamples gesamt:Gesamt: TitelTitelnummerTitelkommentarTitellängenTitelnameTitelnummerTitelTitel:TitelÜbersetzer:Vorangestellte, hintangestellte und doppelte Leerzeichen entfernenTyp:Adresse:Ukrainisch: Außerstande Datei zu öffnenAußerstande %d Datei zu entfernen.Außerstande %d Dateien zu entfernen.Reiter schließen rückgängig machenUnerwartetes Ende der Zeichenkette nach '?'.Fenster gemeinsam minimierenUnbekanntUnbekanntes AlbumUnbekannter InterpretUnbekanntes AlbumUnbekannter TitelUnbekanntes Konvertierungstyp-Zeichen gefunden nach '%%%%'.Unbekanntes Konvertierungstyp-Zeichen gefunden nach '?'.Unbekannte CDUnbekannter FehlerFehlgeschlagene Leseversuche unbegrenzt oft wiederholen (nie überspringen)UngemessenNur ungemessene TitelUnbekanntUnbenanntAlle Feeds aktualisierenFeed aktualisierenDatei-Metadaten aktualisierenDatei-Metadaten aktualisieren …Aktualisiere …Basisnamen nur anstelle des gesamten Pfades benutzen, wenn keine Metadaten verfügbar sind.Manuelles RVA-Level benutzen [dB]Relative Pfade in der Musiksammlungsdatei benutzenNur die lokale Datenbank benutzenBenutzerdefinierter TextBenutzerdefinierte AdresseVBR-KodierungAnbieterAnbieter:Unversehrtheit der Daten überprüfenVersionVertikales Mausrad:Angezeigter Name:Lautstärke:Lautstärke: %sWarnen, falls der Fenstermanager keine Kontrollleiste unterstütztWarnungWavPack WavPack (*.wv)Wenn neue Frames hinzugefügt werden, versuchen ihre Inhalte aus dem äquivalenten Frame eines anderen Tags zu setzen.Alben, die im Album-Modus hinzugefügt wurden, im Zufallsmodus geordnet wiedergebenWin32 Sound API CD-R schreibenCD-RW schreibenDVD-R schreibenDVD+RW schreibenDVD-R schreibenDVD-RAM schreibenDVD-RW schreibenSchreibenJahrJahr:Für die CDDB-Übertragung müssen Sie eine E-Mail-Adresse angeben.Aqualung muss neu gestartet werden, damit die folgenden Veränderungen wirksam werden:_Abbrechen_Dateien hinzufügen …_Durchsuchen …_Konfigurieren_Herunterladen_HochladenInterpretInterpretenam bestenBit doppeltBit FließkommaBit vorzeichenbehaftetBit vorzeichenloszähle …TagTageLaufwerkLaufwerkeKodierungschnellFeedFeedsFeld:iFP-Geräteverwaltung (Herunterlade-Modus)iFP-Geräteverwaltung (Hochlade-Modus)iRiver iFP Treiberunterstützung ElementElementeNeues ElementNeue ElementerAlbumAlbenWurzel / Interpret / Interpret/ Interpret / Album / TitelWurzel / Interpret / Interpret / Album / TitelWurzel / Interpret / Album / TitelWurzel / Album / TitelrwSekundensndfile (WAV) sndfile (WAV, AIFF, etc.) sndio Audio Tag:TitelTitelnicht erreichbarAuswahlfensterbreite benutzenaqualung-0.9beta11/src/po/fr.mo0000644000175000001440000021615211331334313013265 000000000000009M M4%MZMM+OFIQ2R5ST[U WW/W EWQWXW_WwWWW WOWX X 'X4XHX ^XkX |XX X XXXXXXY ,Y8Y>Y SY^YdYmYtY|YY Y Y YYY&Y Z Z9Z UZaZzZZZ&Z Z[ [@[Q[a[t[['[[[[ [4\:\A\E\ U\_\ r\ }\\A\A\ #]/.]^]h/^p^ _#_>*_>i_ __ _(_``(`D`RU`` ` ```$`Ra!da&a"aaabb#b+b /b :bFbUbjb yb;bbbb b b cc#c'*cRcbcuccccccc c c d#d Ad Nd \djd{ddDdd ee!e0e 9eCeJeYeme ee ee eeee e ff#,fPfcfjfqffff fffff g)gj Jj Wjcj=wj2j j!jQkikzkkkkkkll l $l1l Al Nl(Zl(l8l l@l.1m-`mmmmKmQn bn mn%{n n nnnn n n n oo !o+o >oKo Zo hovo|oo ooo"o pp0pBpSpsppppppp p qq&q7qA=qqqqqq0q0rDr Urbrqrrrrr#rr r/s,7sdsis3s (t 3t =tJt`t rt |tt tttt tt ttukuu%u u uuu!u v v!v)vx JxWxfxxxxxxyyA%y gyqyyyy9z Iz Tzazzzz z$z zzzz {{ ({*5{ `{l{s{{{{{{{ { {{#|&|<|E| [|i|,||| |#| }}$#}H} X}d}m}}}}}}"} ~ ~"~(~ /~;~Q~ V~ d~ q~ ~~~ ~~ ~~ %*/@TZb gqy#  K.X3 Ҁ  &^8H( /<K[m ɂӂ  7ۃ 2<BJ cm  Ä́' =Ha%~.Ӆ4,$.Q/-6ކ!*7/b2-Ň0 $1BKQ#`#È ̈ڈ &5GZiy /ʉ  '1N h-t ˊ ֊  " / < HR[n ((֋..5 <H Xd |A[c  č ҍ ߍ   3@O$e GŽ $@G Wevݏ4 >^sz!  Őϐ   %,5T o{-ˑ ! )4C JUl  @ < Q]m  ͓026)i + #%4 9&Fm| &ѕ  (<CU gr!– . F7S! ̗5їjrQ7HF/Ǚ&- Lm ==%,H[kq ̛ٛ *% *6Jd#Μ ֜ 52F y , ̝  + CCO Ξ !)?G ] k:yVş?\m   ' 3 @ L Zgot9zK   +5=DL Q \ f q ~" $* 3=?F0N'ƥܥߥ #) 0<U"qBקSHӭSpn@ Ѳ  1CTheγ ճ& 4I ^ls Ҵ" ' FR#Z ~*ٵ4'A\Qƶ /#4S88޷+C+^ ޸-5-3c5ƹ ""4W i&w=Iܺ &60gB[AcA'(P d9n] . 90C5tx<#:`6(&:BF`r[+ DO Vd x<(<X_w + :HXk#Q3 H S`h2AHbr$2%. 7 CP_ y!(?Vl0}2O J\# /,!K mx(*-@UY ^l%F !X8!RAYh/ "*1Lj 0FI dAq<H9>!\b~uWsA $6F^o!  9+ eo?'-/H3x .*.Y an~Y ;6!r1)ZKj#0-^ sD862Lh, + 7LSi<0&Cjq!z   &+ ;5\    !56W& 2L;^  $. 8,M3z G 3>Qn& <I0Y $  !,J9S 2#+V3%-#<`e$!#E#K oB}  *;Pb$z  !3I O]e t"0 .wo  'B*a. YeB7 $3D\o&3:H$@m  / = KSX&)"$B(gD'L;J:63F,)s>D#7F[-+A _k~ 4'F7n <#6KTp B)  & 4 A O] lz #*6*a9#2Da2 Q6]  "/AWg =(+;_Q $:X tJ )W 7  %*<g|%/  $2 B O([$G7(`| #  *[=%- !BX"r)  0@Uq,D59Yo8 7DK<_#-)Cmt ) -6d2~  # 0' X Wo '    ? T  nf E W As ) ,  9) c i y @ @ 7Pms   /!QX ^k#$ 83-a iw 74 )0 Zf !$a&+2.!8 Wd l#v T 6@uIf&7,<M^pOOir      "'-5>GNSY=b1  *,239*m    & -09vN&tQC$ QuFB#s4eV` Ed z~8` )Qwk_K(]>k/<a3' GP}1jx9qYI>{rT8<!XKrHHT!|QO>|A~^x-*)0f`csbu5(Z:Jge#-;GB+(mCOOf\txM&~BZ4RxD&o=Z%g? [F "']7S&nEc :U;)}eEPJH 9yi _(MPb jLd0R=h|yIYR{w %z/7+"n]U\Yr /2tb zvWqh`]%?!iVqk>5.g3sc6uFL1[XN3\1 0*b'$o:.Cz^mi%U2,w5C.yJ^}n4=}r*3p 56uD;IZn-/8_?Ky~l _$WP<jsFToj9X g0 aqp.;SNl7#v'civ,fHh9 \@EW6lX-MW{"Tm=dS, 7LNV< {+Ma8aU+: kY@V?6p,"oD2tJmDOS12LpGAR|wK A$ldh@!)[fIBeA#G*^4@[ Maximum number of retries: Destination directory is not read-write accessible! Here you should enter a comma-separated list of domains that should be accessed without using the proxy set above. Example: localhost, .localdomain, .my.domain.com Most drives let Aqualung know when a CD has been inserted or removed by providing a 'media changed' flag. However, some drives don't set this flag properly, and thus it may happen that a newly inserted CD remains unnoticed to Aqualung. In such cases, enabling this option should help. Set the drive speed for CD playing in CD-ROM speed units. One speed unit equals to 176 kBps raw data reading speed. Warning: not all drives honor this setting. Lower speed usually means less drive noise. However, when using Paranoia error correction modes for increased accuracy, generally much larger speeds are required to prevent buffer underruns (and thus audible drop-outs). Please note that these settings do not apply to CD Ripping, which always happens with maximum available speed and with error correction modes manually set before every run. The Music Store you selected has a matching Artist and Album, already containing some tracks. If you press OK, these tracks will be removed. The files themselves will be left intact, but they will be removed from the destination Music Store. Press Cancel to get back to change the Artist/Album or the destination Music Store. The file you enter/choose here will set the Lua program to use to format the title. See the Aqualung manual for details. Here is a quick example of what you can use in the file: function playlist_title() return m('artist') .. '-' .. m('title') .. ' (' .. m('album') .. ') (' .. i('filename') .. ')' end The string you enter here will be parsed as a command line before parsing the actual command line parameters. What you enter here will act as a default setting and may or may not be overridden from the 'real' command line. Example: enter '-o alsa -R' below to use ALSA output running realtime as a default. The template string you enter here will be used to construct a single title line from an Artist, a Record and a Track name. These are denoted by %%%%a, %%%%r and %%%%t, respectively. The template string you enter here will be used to construct the filename of the exported files. The Artist, Record and Track names are denoted by %%%%a, %%%%r and %%%%t. The track number and format-dependent file extension are denoted by %%%%n and %%%%x, respectively. The flag %%%%i gives an identifier which is unique within an export session. (%.1f MB) (capacity = %.1f MB) Free space (%.1f MB) Selected: out L out R% of standard deviation% of standard deviation :%.1f MB / %.1f MB%d / %d directories%d / %d files%d of %d songs have format unsupported by your player. Do you want to proceed?%ld Hz(Untitled)(audio only)(choose a category)(error loading image)(no comment)(no description)(no image)(none)*File info*Music StoreDevice statusLocal directoryRemote directorySongs infoTransfer progressA large, coloured fishALSA Audio AbortAbort ongoing updateAborted...AboutAbstractAccessAction:Active song in playlist: AddAdd ArtistAdd RecordAdd TrackAdd URLAdd all items to playlistAdd all items to playlist (Album mode)Add directoryAdd filesAdd files to playlist (Press right mouse button for menu)Add item...Add mouse button commandAdd new artist to this store...Add new artist...Add new items to playlistAdd new items to playlist (Album mode)Add new record to this artist...Add new record...Add new track to this record...Add new track...Add to CommentsAdd to Music StoreAdd to playlistAdd to playlist (Album mode)Add year to the comments of new recordsAdding files to PlaylistAlbumAlbum Sort OrderAlbum imageAlbum mode is the default when adding entire recordsAlbum:AllAll Audio FilesAll FilesAll Playlist FilesAll tracksAll wordsAlways show the tab barAn error occurred while attempting to connect to the CDDB server.An error occurred while submitting the record to the CDDB server.AppearanceApply averaged RVA to tracks of the same recordAqualung is compiled with system tray support, but the status icon could not be embedded in the notification area. Your desktop may not have support for a system tray, or it has not been configured correctly.Aqualung is compiled without LADSPA plugin support. See the About box and the documentation for details.Aqualung is compiled without Sample Rate Converter support. See the About box and the documentation for details.Aqualung playlist (*.xml)ArtistArtist appears to be in all lowercase. Do you want to proceed?Artist appears to be in all uppercase. Do you want to proceed?Artist nameArtist name (lowercase)Artist namesArtist/Album already existing, not emptyArtist/performerArtist:Ask for confirmation when removing itemsAttached PictureAttached Picture frame with no image set! Please set an image or remove the frame.Audio CDAudio dataAudiophileAuthors:Auto-check interval [hour]:Auto-create tracks from these files:Automatic update has been disabled for all feeds in the Podcasts store popup menu.Automatically add CDs to PlaylistAutomatically remove CDs from PlaylistAutomatically roll to active trackAutomatically update feedsAvailable connectionsAvailable pluginsAvailable skinsAverageBPMBack coverBalance: %sBand/OrchestraBand/artist logotypeBand/orchestraBandwidth:Batch update & encode (mass tagger, CD ripper, file export)Batch-update file metadata...BatteryBeginBibliographyBig timer: Binary ObjectBitrate [kbps]:BrowseBuild / Update store from filesystem...Build version: Build/Update storeBuilding store from filesystemButtonC2 Error CorrectionCD drive speed:CDDA (Audio CD) support CDDBCDDB (not available)CDDB lookupCDDB queryCDDB query for this CD...CDDB query for this record...CDDB server:CDDB support Calculate RVACalculate volumeCalculate volume (recursive)Calculating volume levelCannot write to selected directory. Please select another directory.CapitalizationCapitalize: Case sensitiveCatalog NumberCategoryCategory:ChangeChange balanceChange current songChange song positionChange volumeChannel count:Channels:Clear connectionsClear listClick here to set mouse buttonCloseClose other tabsClose tabClose trayClose window when completeClose window when transfer completeCollapse all itemsColorsColumnCombine play and pause buttonsCommandCommentCommentsComments:Commercial InformationComposerCompressed modules (*.bz2)Compressed modules (*.gz)Compressed modules (*.gz, *.bz2)Compression level:Compression: Extra HighCompression: FastCompression: HighCompression: InsaneCompression: NormalConductorConnect via HTTP proxyConnecting to CDDB server...Connection timeout [sec]:ContactContent GroupConversion error in field %s: '%s' does not conform to format '%s'!Conversion to target charset failedConvert underscore to spaceCopyCopyrightCopyright/Legal InformationCore design, engineering & programming: Correct existing recordCould not load image from: %sCover artCreate a new directoryCreate directoryCreate empty storeCreate empty store...Create subdirectories for albumsCreate subdirectories for artistsCurrent file: Cut selectedDSPDateDebut AlbumDecoding support:Default cover width:Delete downloaded items from the filesystemDescriptionDescription:DestinationDetect media changeDevice is busy. (Aqualung was unable to claim its interface.)Device is not responding. Try jiggling the handle.Device path:Direct connection to the InternetDirectory '%s' will be removed with its entire contents. Do you want to proceed?Directory drivenDirectory nameDirectory name (lowercase)Directory structureDisable all pluginsDisable control buttons reliefDisable manual ejectDisable skin supportDiscDisc infoDisc info...Discard changesDo not closeDo not exitDo not magnify images with smaller widthDo not reencode files matching wildcard:Do not reencode files already being in the target formatDo nothingDo you want to save store "%s" before removing from Music Store?Do you want to save the store before removing?Don't show cover thumbnail in the main windowDoneDownload directory:Downloading %d/%d (%d%%) ...Drag and drop entries in the list to set the feed order in the Music Store.Drag and drop entries in the list below to set the column order in the Playlist.Drive infoDrive info...Drop statistical aberrations based onDual channelDuration:During performanceDuring recordingEAN/UPCEdit ArtistEdit RecordEdit StoreEdit TrackEdit artist...Edit feedEdit feed settingsEdit item...Edit record...Edit store...Edit track...EjectEmail address for submission:Embed playlist into main windowEmphasis:Emphasis: noneEmphasis: reservedEnable Music Store tree node iconsEnable all pluginsEnable playback RVAEnable rules hintEnable statusbarEnable statusbar in Music StoreEnable statusbar in playlistEnable systrayEnable toolbarEnable toolbar in Music StoreEnable tooltipsEnable tree node iconsEnabledEncoded byEncoding TimeEncoding support:Enqueue playlistErrorError converting field %s to Year: '%s' is not an integer number!Error in format stringError in title format stringExact matches onlyExclude files matching wildcardExpand Stores on startupExpected '}' after '{', but end of string found.Export all items...Export artist...Export filesExport item...Export new items...Export record...Export store...Export track...Exporting filesExtended Title Format Files (*.lua)Extended data:FLAC PicturesFailed to set metadata for the following files:Failed to write metadata to file. Reason: %sFileFile "%s" does not exist or your write permission has been withdrawn. Check if the partition containing the store file has been unmounted.File '%s' will be removed. Do you want to proceed?File OwnerFile TypeFile format:File icon (32x32 PNG)File icon (other)File infoFile info...File is not writableFile name: File:FilenameFilename template:Filename:Files selected for removalFilesystemFilterFirst word onlyFollows the directory structure to identify the artists and records. The files are added on a record basis.FontsForce TOC re-read on every drive scanForce case: Force other letters to lowercaseFormatFormat:Free Lossless Audio Codec (FLAC) Free spaceFront coverGeneralGeneric StreamMetaGenreGenre:German: Graphics:Hard reset deviceHelpHide AqualungHide comment paneHide the Music Store comment paneHomepage:Horizontal mouse wheel:Hungarian: IDISBNISRCIcy-DescriptionIcy-GenreIcy-NameIdleIllustrationImplicit command lineImport Comment tagImport Replaygain tag as manual RVAImport as ArtistImport as RVAImport as RecordImport as Sort KeyImport as TitleImport as Track No.Import as YearIn any caseInclude only files matching wildcardIndependentIndexInitial keyInputsInstrumentsInstruments:Internal errorInternet Radio Station NameInternet Radio Station OwnerInterpreted/RemixedInvalid 'Genre' field valueInvalid 'Track no.' field valueInvert current stateInvert selectionInvolved PeopleIt is very likely that the year is wrong. Do you want to proceed?Italian: JACK Audio Server JACK Port SetupJACK connection lostJACK has either been shutdown or it disconnected Aqualung because it was not fast enough. All you can do now is restart both JACK and Aqualung.JACK port setupJapanese: Joint stereoKeep main window always on topKey: LADSPA patch builderLADSPA plugin support LAME (MP3) LAVC (AC3, AAC, WavPack, WMA, etc.) Label CodeLanguageLayer ILayer IILayer IIILead artist/performerLeaflet pageLeft and right mouse buttons are reserved.Left buttonLengthLength:LicenseLimitsLinear threshold [dB]Linear threshold [dB] :Listening environment:Living roomLoad playlistLoad playlist in new tabLoad settings from Music Store fileLocal CDDB directory:LocationLocation and filenameLogo, icons: Loop playback support Lua (programmable title formatting) support Lyricist/Text WriterLyricist/text writerMIME type: %sMOD Audio (MOD, S3M, XM, IT, etc.) MONOMP3 Playlist (*.m3u)MPEG Audio (MPEG 1-2.5 Layer I-III) MPEG StreamMetaMain windowMatches:Maximum number of items:Maximum number of retries:Maximum space to use [MB]:MediaMemory allocation errorMetadataMetadata editor (File info dialog)Middle buttonMiscellaneousMode:Model:Module infoMonkey's Audio Codec MoodMount RainierMouse buttonMouse buttonsMouse wheelMovie/video screen captureMultimedia Playlist (*.pls)Musepack Musepack ReplayGainMusic StoreMusic Store Files (*.xml)Music Store: Musician CreditsMuteNameName to sort by:Name transformationName:New tabNextNext songNo discNo matching record found.No metadata support for this formatNo outputNo proxy for:No suitable iRiver iFP device found. Perhaps it is unplugged or turned off.No.Noisy workshopNoneNone of the selected songs has format supported by your player. Do you want to proceed?OSS Audio OfficeOfficial Artist WebsiteOfficial Audio File WebsiteOfficial Audio Source WebsiteOfficial Radio Station WebsiteOgg Speex Ogg Vorbis Ogg Xiph CommentsOne or more stores in Music Store have been modified. Do you want to save them before exiting?One song has format unsupported by your player. Do you want to proceed?Only if unmeasuredOpenBSD compatibility, metadata tweaks: Optional features:OrganizationOriginal AlbumOriginal ArtistOriginal FilenameOriginal LyricistOriginal Release TimeOtherOutputOutput driver support:Output:OutputsOverall: Override skin settingsParanoiaParanoia error correctionPart Of A SetPathPaths must either be absolute or starting with a tilde, which will be expanded to the user's home directory. Drag and drop entries in the list to set the store order in the Music Store.Paths must either be absolute or starting with a tilde.Paths to Music Store databasesPatterns:PausePaymentPerform overlapped readsPerformerPerformer Sort OrderPicture type:PlayPlay CD AudioPlay/PausePlay/Pause songPlay/Stop songPlayback RVA is currently disabled. Do you want to enable it now?PlaylistPlaylist DelayPlaylist column orderPlaylist: Please enter a new name.Please enter directory name.Please select a Music Store database.Please select a Programable Title Format File.Please select a local path.Please select at least one valid song from playlist.Please select the audio file for this track.Please select the audio files for this record.Please select the directory for exported files.Please select the directory for ripped files.Please select the download directory for this podcast.Please select the root directory.Please select the xml file for this store.Please specify the file to load the image from.Please specify the file to load the playlist from.Please specify the file to save the image to.Please specify the file to save the playlist to.Podcast URL:Podcast support PodcastsPort:Position: %d%%Post Fader (after Volume & Balance)Pre Fader (before Volume & Balance)Predefined transformationsPreviousPrevious songProcessing metadataProcessing:ProducedProfile: BraindeadProfile: InsaneProfile: RadioProfile: StandardProfile: TelephoneProfile: ThumbProfile: XtremeProgrammable title format fileProgramming, GUI engineering: ProgressProgress:Protocol for querying (direct connection only):Proxy host:Proxy settingsPublication RightPublisherPublisher's Official WebsitePublisher/studio logotypePulseAudio Put control buttons at the bottom of playlistQuitRVARVA for Unmeasured Files [dB] :RVA valuesRead CD+GRead CD-DARead CD-RRead CD-RWRead DVD+RRead DVD+RWRead DVD-RRead DVD-RAMRead DVD-ROMRead DVD-RWRead ISRCRead MCNRead Mode 2 Form 1Read Mode 2 Form 2Read multiple sessionsReadingReading fileReally remove "%s" from the Music Store?Really remove '%s' from the Music Store?Really remove store "%s" from the Music Store?ReasonRecordRecord DateRecord LocationRecord nameRecord name (lowercase)Record titlesRecording location/studioRecursive search from the root directory for audio files. The files are processed independently, so only metadata and filename transformation are available.Reference volume [dBFS] :RefreshRegexp matches empty stringRegexp:Regular expressionRelatedRelease TimeRemoveRemove ArtistRemove RecordRemove StoreRemove TrackRemove allRemove artistRemove deadRemove feedRemove file extensionRemove filesRemove item...Remove leading numberRemove non-existing files from storeRemove older items [day]:Remove recordRemove selectedRemove selected songs from playlist (Press right mouse button for menu)Remove storeRemove trackRemoving non-existing filesRenameRename playlistReorder feedsRepeat all songsRepeat current songReplace:ReplayGain Album GainReplayGain Album PeakReplayGain Reference LoudnessReplayGain Track GainReplayGain Track PeakReplayGain tag to use (with fallback to the other): Reread data for existing tracksReread file metadataRescanResumeRetrieving matches from server...Revision:Right buttonRipRip CDRip CD...Ripping CD tracksRoll to active songRoot path:Running pluginsRussian: SRC Type: STEREOSTOPPINGSample Rate Converter support Sample Rate Converter typeSamplerate:SamplesSamples:SandboxSaveSave all playlistsSave all storesSave and closeSave and restore the playlist on exit/startupSave playlistSave playlist periodically [min]:Save storeScanning filesSearchSearch in:Search the Music StoreSearch the PlaylistSearch...SelectSelect a font...Select allSelect all songs in playlist (Press right mouse button for menu)Select build typeSelect directorySelect filesSelect first and close windowSelect juke-box discSelect noneSelected files:Send to iFP deviceSeparateSet SubtitleSet drive speedSettingsShow AqualungShow RVA valuesShow active track name in boldShow close button in tabShow cover thumbnail for Music Store tracks onlyShow hidden files and directories in file choosersShow song name in the main window's titleShow soundfile size in statusbarShow tags tab first in the file info dialogShow track lengthsShuffle songsSimple view in LADSPA patch builderSingle channelSizeSkin chooserSkin support, look & feel, GUI hacks: Small timers: SoftwareSong in playlist: Song info: Song title: Sort artists bySort records bySound Files (*.wav, *.aiff, *.au, ...)SourceSource file:Start minimizedStatusbar: Steepness [dB/dB] :StereoStop adding filesStop adding songsStructure:Subdirectory name length limit:Submit CD to CDDB database...Submit new recordSubmit record to CDDB database...Subscribe to new feedSubtitleSuccessSwedish: SystraySystray support Tag files with metadataTagging TimeTags to add when creating or updating MPEG audio files:Target directory for ripped filesTarget directory:Target file:TestThe email address provided for submission is invalid.The information below is reported by the drive, and may not reflect the actual capabilities of the device.The selected files will be deleted from the filesystem. No recovery will be possible after this operation. Do you want to proceed?The selected song has format unsupported by your player. Do you want to proceed?The specified store has already been added to the list.The store '%s' already exists. Add it on the Settings/Music Store tab.There are unsaved changes to the file metadata.This Aqualung binary is compiled with:This CD does not contain CD-Text information.This button is already assigned.Timeout for socket I/O:TitleTitle FormatTitle Sort OrderTitle appears to be in all lowercase. Do you want to proceed?Title appears to be in all uppercase. Do you want to proceed?Title:Toggle LADSPA patch builderToggle music storeToggle playlistTotalTotal samples:Total: TrackTrack No.Track commentTrack lengthsTrack nameTrack numberTrack titlesTrack:TracksTranslators:Trim leading, tailing and duplicate spacesType:URL:Ukrainian: Unable to open fileUnable to remove %d file.Unable to remove %d files.Undo close tabUnexpected end of string after '?'.United windows minimizationUnknownUnknown AlbumUnknown ArtistUnknown RecordUnknown TrackUnknown conversion type character found after '%%%%'.Unknown conversion type character found after '?'.Unknown discUnknown errorUnlimited retry on failed reads (never skip)UnmeasuredUnmeasured tracks onlyUnrecognizedUntitledUpdate all feedsUpdate feedUpdate file metadataUpdate file metadata...Updating...Use basename only instead of full path if no metadata is available.Use manual RVA value [dB]Use relative paths in store fileUse the local database onlyUser Defined TextUser Defined URLVBR encodingVendorVendor:Verify data integrityVersionVertical mouse wheel:Visible name:Volume level:Warn me if the Window Manager does not support system trayWarningWavPack When adding new frames, try to set their contents from another tag's equivalent frame.When shuffling, records added in Album mode are played in orderWin32 Sound API Win32 Sound API This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.Write CD-RWrite CD-RWWrite DVD+RWrite DVD+RWWrite DVD-RWrite DVD-RAMWrite DVD-RWWritingYearYear:You have to provide an email address for CDDB submission.You will need to restart Aqualung for the following changes to take effect:_Abort_Add files..._Browse..._Configure_Download_Uploadartistartistsbestbit doublebit floatbit signedbit unsignedcounting...daydaysdrivedrivesencodingfastfeedfeedsfield:iFP device manager (download mode)iFP device manager (upload mode)iRiver iFP driver support itemitemsnew itemnew itemsrrecordrecordsroot / artist / artist / artist / record / trackroot / artist / artist / record / trackroot / artist / record / trackroot / record / trackrwsecondssndfile (WAV) sndfile (WAV, AIFF, etc.) sndio Audio tag:tracktracksunreachableuse browser window widthProject-Id-Version: Report-Msgid-Bugs-To: POT-Creation-Date: 2010-01-12 22:03+0100 PO-Revision-Date: 2010-01-31 12:50+0100 Last-Translator: Louis Opter Language-Team: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Nombre maximale de retentatives : Le dossier cible n'est pas accessible en lecture et en écriture. Vous devriez entrer ici une liste de domaines séparés par des virgules qui sont accessible sans le serveur mandataire configuré plus haut. Exemple : localhost, .localdomain, .my.domain.com La plupart des lecteurs notifient Aqualung quand un CD-ROM a été inséré ou retiŕe. Cependant, certains lecteurs ne le font pas correctement et parfois Aqualung ne réagit pas quand un CD-ROM a été inséré. Dans ce cas activer cette option peut aider. Configurez la vitesse du lecteur CD-ROM. Une unité de vitesse correspond à 176 kO de données brutes par seconde. Attention : certains lecteurs n'utilisent pas cette préférence. Des vitesses basses signifient généralement moins de bruit. Cependant, en utilisant les modes de corrections d'erreurs de Paranoia (pour plus de précision); des vitesses beaucoup plus grandes sont souvent nécessaires pour éviter des tampons vides (et donc des moments de blanc audibles). Veuillez noter que ces préférences ne s'appliquent pas lors de l'encodage de CD-ROM, qui ont toujours lieu à la plus grande vitesse possible et avec les modes de corrections d'erreurs choisis avant chaque encodage. La Discothèque que vous avez sélectionné a une correspondance avec un Artiste et un Album contenant déjà certaines pistes. Si vous appuyez sur OK, ces pistes seront enlevées. Les fichiers eux mêmes seront laissés intacts, mais ils seront enlevé de la Discothèque cible. Appuyez sur Annuler pour revenir en arrière pour changer les Artistes/Albumsou la Discothèque cible. Le fichier que vous choisissez ici représente le programme Lua à utiliser pour formater le titre. Consultez le manuel d'Aqualung pour les détails. Voici un exemple de ce que vous pouvez utiliser : function playlist_title() return m('artist') .. '-' .. m('title') .. ' (' .. m('album') .. ') (' .. i('filename') .. ')' end La chaîne de caractères que vous entrez ici sera analysée avant les arguments donnés à Aqualung. Ce que vous entrez ici va agir comme un paramètre par défaut qui peut (ou pas) être surchargé depuis la 'vraie' ligne de commande. Exemple : entrez ci-dessous : '-o alsa -R' pour utiliser la sortie ALSA en temps réel par défaut. Le patron de chaîne de caractères que vous entrez ici sera utilisé pour générer un titre depuis un Artiste, un Album et un numéro de Piste. Ils sont respectivement notés par : %%%%a, %%%%r et %%%%t. Le patron de chaîne de caractères que vous entrez ici sera utilisé pour générer les noms des fichiers exportés. L'artiste, l'album et le nom des pistes sont notés par %%%%a, %%%%r et %%%%t. Le numéro de piste et l'extension du fichier sont respectivement notés %%%%n et %%%%x. Le drapeau %%%%i donne un identifiant qui est unique pour une session d'export. (%.1f MO) (capacité = %.1f MO) Espace libre (%.1f MO) Sélectioné: sortie G sortie D% de la variance% de la variance :%.1f MO / %.1f MO%d / %d dossiers%d / %d fichiers%d sur %d pistes sont dans un format qui n'est pas supporté par votre lecteur. Voulez vous continuer ?%ld Hz(Sans titre)(audio seulement)(choisir une catégorie)(erreur lors du chargement de l'image)(pas de commentaire)(pas de description)(pas d'image)(rien)*Informations sur le fichier*DiscothèqueÉtat du périphériqueDossier localDossier distantInformations sur les pistesStatus du transfertUn poisson lumineux et coloréALSA Audio AbandonAbandonner la mise à jour en coursAbandonné...A proposRésuméAccèsAction :Chanson active dans la liste de lecture : AjouterAjouter un ArtisteAjouter un AlbumAjouter une PisteAjouter une URLAjouter tous les éléments dans la liste de lectureAjouter tous les éléments dans la liste de lecture (mode Album)Ajouter un dossierAjouter des fichiersAjouter des fichiers dans la liste de lecture (Faites un clic droit pour le menu)Ajouter...Ajouter une commande sur le bouton de la sourisAjouter un nouvel artiste dans cette discothèque...Ajouter un nouvel artiste...Ajouter les nouveaux éléments dans la liste de lectureAjouter les nouveaux éléments dans la liste de lectureAjouter de nouveaux album à cet artiste...Ajouter un nouvel album...Ajouter de nouvelles pistes à cet album...Ajouter une nouvelle piste...Ajouter aux commentairesAjouter dans la DiscothèqueAjouter dans la liste de lectureAjouter dans la liste de lecture (mode Album)Ajouter l'année aux commentaires des nouveaux albumsAjout en cours de fichiers dans la liste de lectureAlbumOrdre de Tri de l'AlbumImage de l'AlbumLe mode Album est le mode par défaut lors de l'ajoutAlbum :ToutTous les Fichiers AudiosTout les fichiersTous les Types de Liste de LectureToutes les pistesTous les motsToujours afficher la barre des ongletsUne erreur est survenue lors de la connexion au serveur CDDB.Une erreur est survenue lors de la proposition de l'album au serveur CDDBApparenceAppliquer une moyenne RVA sur les piste du même albumAqualung n'arrive pas à utiliser la zone de notification. Peut-être que votre gestionnaire de fenêtre ne supporte pas la zone de notification ou qu'il est mal configuré.Cet Aqualung a été généré sans le support de LADSPA. Consultez la fenêtre 'A propos' et la documentation pour plus de détails.Cet Aqualung a été généré sans le support de la Conversion du Taux d'Échantillonage. Consultez la fenêtre 'A propos' et la documentation pour plus de détails.Liste de lecture (*.xml)ArtisteL'artiste est entièrement en minuscules. Voulez vous continuer ?L'artiste est entièrement en majuscules. Voulez vous continuer ?Nom de l'artisteNom de l'artiste (minuscules)Noms de l'ArtisteArtiste/Album déjà existant, non videArtiste/InterprèteArtiste :Demander confirmation lors de la suppression d'élémentsImage attachéeUn cadre pour une image est présent mais pas l'image ! Mettez une image ou enlevez le cadre.CD AudioDonnées audioAudiophileAuteurs :Interval de vérification automatique [heures] :Créer automatiquement les pistes pour ces fichiers :Les mises à jours automatiques ont été désactivées pour tous les flux dans le menu de la discothèque des Podcasts.Ajouter automatiquement les CD-ROMs dans la liste de lectureEnlever automatiquement les CD-ROMs de la liste de lectureBouger le curseur automatiquement vers la piste activeAutomatiquement mettre à jour les fluxsConnexions disponiblesModules disponiblesThèmes disponiblesMoyenneBPMArrière de la couvertureÉquilibrage : %sGroupe/OrchestreLogo du groupe/artisteGroupe/OrchestreBande passante :Mise à jour & encodage scripté (étiquettage de masse, encodage de CD, export de fichier)Mise à jour scripté des méta-données...Batterie :DébutBibliographieGrande minuterie : Objet BinaireBitrate [kbps] :ExplorerGénérer / Mettre à jour depuis le système de fichiers...Version générée :Contruire/Mettre à jour la discothèqueConstruire la discothèque à partir du système de fichiersBoutonCorrection d'erreurs C2Vitesse du lecteur CD-ROM :Support CDDA (CD Audio) CDDBCDDB (non disponible)Interogation de CDDBRequête vers CDDBRequête CDDB pour ce CD...Requête CDDB pour cet album...Serveur CDDB :Support CDDB Calculer le RVACalculer le volumeCalculer le volume (récursif)Calcul du niveau de volume en coursImpossible d'écrire vers le dossier sélectionné. Veuillez en choisir un autre.CapitalisationCapitaliser : Sensible à la casseNuméro du catalogueCatégorieCatégorie :ChangerChanger l'équilibrageChanger la chanson couranteChanger la chanson de positionChanger le volumeNombre de canaux :Canaux :Effacer les connexionsVider la listeCliquer ici pour configurer le bouton de la sourisFermerFermer les autres ongletsFermet l'ongletFermer le tiroirFermer la fenêtre une fois terminéFermer la fenêtre quand le transfert est terminéReplier tous les élémentsCouleursColonneCombiner les boutons pause et lectureCommandeCommentaireCommentairesCommentaires :Informations CommercialesCompositeurModules compressés (*.bz2)Modules compressés (*.gz)Modules compressés (*.gz, *.bz2)Niveau de compression :Compression : Très ÉlevéeCompression : RapideCompression : ÉlevéeCompression : InsenséCompression : NormaleChef d'orchestreConnexion via un serveur HTTP mandataire (proxy)Connexion au serveur CDDB...Délai d'attente maximal pour la connexion [sec] :ContactStyleErreur de conversion dans le champs %s : '%s' ne correspond pas au format '%s'!La conversion vers le nouveau format d'encodage des caractères a échouéConvertir les tirets bas en espacesCopierCopyrightCopyright/Informations LégalesArchitecture, développement & programmation : Correction de l'album existantImpossible de charger l'image: %sCouvertureCréer un nouveau dossierCréer un dossierCréer une discothèque videCréer une discothèqueCréer des sous-dossiers pour les albumsCréer des sous-dossiers pour les artistesFichier courant : Coupez la sélectionDSPDatePremier AlbumSupport du décodage :Largeur par defaut de la couverture :Supprimer les éléments téléchargés depuis le système de fichiersDescriptionDescription :DestinationDétecter le changement de médiaLe périphérique est déjà utilisé. (Aqualung n'a pas pus réclamer son utilisation.)Le périphérique ne répond pas.Chemin du périphérique :Connexion directe vers InternetLe dossier '%s' sera effacé avec tout ce qu'il contient. Voulez vous continuer ?Gérer par les dossiersNom du dossierNom du dossier (minuscules)Structure du dossierDésactiver tous les modulesDésactiver le relief des boutons de contrôlesDésactiver l'éjection manuelleDésactiver le support des thèmesDisqueInformations sur le disqueInformations sur le disque...Abandonner les changementsNe pas fermerNe pas quitterNe pas agrandir les images qui sont trop petitesNe pas encoder de nouveaux les fichiers qui correspondent à ce joker:Ne pas encoder de nouveau les fichiers qui sont déjà dans le bon formatNe fait rienVoulez vous sauvegarder la discothèque "%s" avant de l'enlever ?Voulez vous sauvegarder la discothèque avant de l'enlever ?Ne pas montrer la miniature de la couverture dans la fenêtre principaleFiniDossier de téléchargement :Téléchargement %d/%d (%d%%) ...Glisser et déposer les entrées dans la liste pour choisir l'ordre des flux dans la Discothèque.Glissez et déposez les éléments de la liste en dessous pour régler l'ordre des colonnes dans la liste de lecture.Informations sur le lecteurInformations sur le lecteur...Ne pas prendre en compte les aberrations statistiques basées surDouble canalDuré :Pendant l'interprètationPendant l'enregistrementEAN/UPCÉditer l'artisteËditer l'AlbumÉditer la discothèqueÉditer la PisteÉditer l'artiste...Éditer le fluxÉditer les préférences du fluxÉditer...Éditer l'album...Éditer la discothèque...Éditer la piste...ÉjecterCourriel pour la proposition :Intégrer la liste de lecture dans la fenêtre principaleEmphase :Emphase : aucuneEmphase : réservéAfficher les icônes des noeuds dans l'arbre de la discothèqueActiver tous les modulesActiver le playback RVAActiver les indications sur les règlesActiver la barre de statusActiver la barre de status dans la discothèqueActiver la barre de status dans la liste de lectureActiver la zone de notificationsActiver la barre d'outilsActiver la barre d'outils dans la discothèqueActiver les info-bullesAfficher les icônes des noeuds des arbresActivéEncodé avecDate d'encodageSupport de l'encodage :Rajouter une liste de lectureErreurErreur lors de la conversion du champs %s vers Année : '%s' n'est pas un nombre entier !Erreur dans la chaîne de formatErreur dans la chaîne de caractères de formatage du titreCorrespondances exactes seulementExclure les fichiers qui correspondent aux jokersDérouler les discothèques au démarrage'}' était attendu après '{', mais la fin de la chaîne de caractères à été trouvée.Expoter tous les éléments...Exporter l'artiste...Exporter les fichiersExporter un élément...Exporter les nouveaux éléments...Expoter l'album...Expoter la discothèque...Exporter la piste...Export des fichiers...Fichiers de Format de Titres Formatables (*.lua)Données étendues :Images FLACImpossible de mettre les méta-données pour les fichiers suivants :Impossible d'enregistrer les méta-données. Raison : %sFichierLe fichier "%s" n'existe pas ou vos droits d'écriture ont été retirés. Vérifier si la paritition contenant la discothèque n'a pas été éjectée.Le fichier '%s' sera effacé. Voulez vous continuer ?Propriétaire du FichierFormat du FichierFormat du fichier :Icône du fichier (PNG 32x32)Icône du fichier (autre)Informations sur le fichierInformations sur le fichier...Le fichier n'est pas accessible en écritureNom du fichier : Fichier :Nom du fichierPatron du nom du fichier :Nom du fichier :Fichiers sélectionnés pour la suppressionSystème de fichiersFiltrePremier mot seulementSuivre la structure des dossiers pour identifier les artistes et les albums. Les fichiers seront ajoutés sur la base des albums.PolicesForcer la relecture du sommaire à chaque analyse du lecteurForcer la casse : Forcer les autres lettres en minusculeFormatFormat :Free Lossless Audio Codec (FLAC) Espace libreFront de la couvertureGénéralMéta-données du FluxGenreGenre :Allemand : Graphismes :Redémarrer le périphériqueAideCacher AqualungCacher le panneau de commentaireCacher la discothèque dans le panneau de commentairePage d'accueil :Roue horizontale de la souris :Hongrois : IDISBNISRCDescriptionsGenreNoms des StationsEn attenteIllustrationLigne de commande impliciteImporter l'étiquette CommentaireImporter l'étiquette Replaygain comme des RVA manuelsImporter comme ArtisteImporter en tant que RVAImporter en tant qu'AlbumImporter comme clé de triImporter comme un titreImportrer en tant que numéro de pisteImporter comme une annéeDans tous les casInclure seulement les fichiers qui correspondent aux jokersIndépendantIndexClefEntréesInstrumentsInstruments :Erreur interneNom de la Station Radio sur InternetPropriétaire de la Station Radio sur InternetInterprété/RemixéLa valeur du champs 'Genre' n'est pas valideLa valeur du champs 'No. de Piste' n'est pas valideInverser l'état courantInverser la sélectionParticipantsIl est très probable que l'année soit fausse. Voulez vous continuer ?Italien : JACK Audio Server Configuration des Ports JACKConnexion avec JACK perdueSoit JACK a été éteint soit il a déconnecté Aqualung car il n'était pas assez rapide. Vous n'avez pas d'autres choix que de relancer JACK et Aqualung.Configuration de JACKJaponnais : Stéréo jointeToujours garder la fenêtre principale au dessusClef : Configuration LADSPASupport du plugin LADSPA LAME (MP3) LAVC (AC3, AAC, WavPack, WMA, etc.) Identifiant du LabelLangueCouche ICouche IICouche IIIArtiste/Interprète principalBrochureLes boutons gauche et droit de la souris sont réservés.Bouton gaucheDuréDuręe :LicenceLimitesSeuil linéaire [dB]Seuil linéaire [dB] :Environnement d'écoute :SalonCharger une liste de lectureCharger une liste de lecture dans un nouvel ongletCharge les réglages de fichier Music StoreDossier CDDB local :LieuDestination et nom du fichierLogo, icônes : Support de lecture en boucle Support de Lua (formatage programmable des titres) ParolesParolestype MIME : %sMOD Audio (MOD, S3M, XM, IT, etc.) MONOListe de lecture MP3 (*.m3u)MPEG Audio (MPEG 1-2.5 Layer I-III) Méta-données du Flux MPEGFenêtre PrincipaleConcordances :Nombre maximum d'éléments :Nombre maximal de tentatives :Espace maximal à utiliser [MB] :MediaImpossible d'allouer de la mémoireMeta-donnéesÉditeur de méta-données (Fenêtre d'information sur du fichier)Bouton du milieuDiversMode :Modèle :Informations du ModuleCodec Monkey's Audio HumeurMont RainierBouton de sourisBoutons de la sourisRoue de la sourisCapture d'un film/videoListe de lecture Multimédia (*.pls)Musepack ReplayGain MusepackDiscothèqueFichiers de Discothèques (*.xml)Discothèque : Musiciens ParticipantsMuetNomNom par lequel trier :Transformation du nomNom :Nouvel ongletSuivantPiste suivantePas de disquePas d'album correspondant trouvé.Pas de support des méta-données pour ce formatPas de sortieNe pas passer par le serveur mandataire pour :Aucun périphérique iRiver iFP utilisable n'a été trouvé. Peut-être qu'il n'est pas branché ou qu'il est éteint.No.Magasin bruyantAucunAucune des pistes que vous avez sélectionnées ne sont supportées par votre lecteur. Voulez vous continuer ?OSS Audio BureauSite Officiel de l'ArtisteSite Officiel du Fichier AudioSite Officel de la Source du Fichier AudioSite Officiel de la Station Radio sur InternetOgg Speex Ogg Vorbis Commentaires Ogg XiphDes discothèques ont été modifiées. Souhaitez vous les sauvegarder avant de quitter ?Une des pistes est dans un format qui n'est pas supporté par votre lecteur. Voulez vous continuer ?Seulement si non-mesuréCompatibilité OpenBSD, bidouilles des meta-données : Fonctionnalités optionnellesOrganisationAlbum OriginalArtiste OriginalNom Original du FichierParoles OriginalesDate de Sortie OriginaleAutreSortiePilotes audio supportés :Sortie :SortiesTotal : Surcharger les préférences du thèmeParanoiaErreur de connexion à ParanoiaPartie d'une CompilationCheminLes chemins de fichiers doivent être absolus ou commencer avec ~, qui sera remplacé par le répertoire personnel de l'utilisateur. Glissez et déposez les entrées dans la liste pour configurer l'ordre de tri dans la Discothèque.Les chemins de fichiers doivent être soit absolus soit commencer avec ~Chemins de fichiers vers les base de données de la discothèqueMotifs :PausePaiementEffectue des lecturesInterprèteOrdre de Tri des InterprètesType d'image :LectureJouer un CD AudioLecture/PauseLecture/PauseLecture/StopLe playback RVA est actuellement désactivé. Souhaitez vous l'activer maintenant ?Liste de lectureDuré du Silence Entre les Pistes (ms)Ordre des colonnes de la liste de lectureListe de lecture : Veuillez entrer le nouveau nom.Veuillez entrer le nom d'un dossier.Veuillez sélectionner une discothèque.Veuillez sélectionner un Fichier de Format de Titres Programmables.Veuillez sélectionner un chemin local.Veuillez sélectionner au moins une piste valide depuis la liste de lecture.Veuillez sélectionner les fichiers audio pour cette piste.Veuillez sélectionner les fichiers audios pour cet album.Veuillez choisir un dossier où exporter les fichiers.Sélectionnez le dossier pour les fichiers copiés.Veuillez sélectionner le dossier de téléchargement pour ce podcast.Merci de sélectionner le dossier racine.Veuillez sélectionner le fichier xml pour cette discothèque.Choisissez une image.Veuillez spécifier depuis quel fichier charger la liste de lecture.Choisissez où enregistrer l'image.Veuillez spécifier vers quel fichier enregistrer la liste de lecture.URL du Podcast :Support du Podcast PodcastsPort :Position : %s%%Post Fader (après le Volume & l'ÉquilibragePre Fader (avant le Volume & l'ÉquilibrageTransformations prédéfiniesPrécédentPiste précédenteTraitement des meta-donnéesTraitement :ProduitProfile : Encéphalogramme platProfile : InsenséProfile : RadioProfile : StandardProfile : TéléphoneProfile : Petite tailleProfile : ExtremeFichier du format de titre programmableProgrammation et conception de l'interface graphique : ProgressionProgression :Protocole pour les requêtes (connexion directe seulement) :Serveur mandataire :Préférences du serveur mandataireDroit de publicationÉditeurSite Officiel de l'ÉditeurLogo du studio/éditeurPulseAudio Placer les boutons de contrôles en dessous de la liste de lectureQuitterRVARVA pour les Fichiers non Mesurés [dB] :Valeurs RVALire un CD+GLire un CD-DALire un CD-RLire un CD-RWLire un DVD+RLire un DVD+RWLire un DVD-RLire un DVD-RAMLire un DVD-ROMLire un DVD-RWLier le ISRCLire le MCNMode de Lecture 2 Forme 1Mode de Lecture 2 Forme 2Lire les sessions multiplesLecture en coursLecture du fichierRetirer vraiment "%s" de la discothèque ?Retirer vraiment '%s' de la Discothèque ?Retirer vraiment la discothèque "%s" des Discothèques ?RaisonAlbumDate d'enregistrementLieu d'enregistrementNom de l'albumNom de l'enregistrement (minuscule)Titres de l'AlbumLieu/Studio d'enregistrementRecherche récursive sur le dossier racine pour les fichiers audio. Les fichiers sont traités indépendamment, donc seulement les méta-données et les transformations de noms de fichiers seront disponibles.Volume de référence [dBFS] :RafraîchirL'expression regulière correspond à une chaîne videExpression :Expression régulièreLié àDate de SortieEffacerRetirer l'ArtisteRetirer l'AlbumRetirer la discothèqueRetirer la PisteTout retirerEnlever l'artisteEnlever les périmésRetirer le fluxRetirer l'extension du fichierRetirer les fichiersRetirer...Retirer les premiers chiffresRetirer les fichiers qui n'existent plus dans la discothèqueRetirer les anciens éléments [jours] :Enlever l'albumRetirer la sélectionEnlever les chansons sélectionnées de la liste de lecture (Faites un clic droit pour le menu)Retirer la discothèqueRetirer la piste...Enlever les fichiers inexistantsRenommerRenommer la liste de lectureRéordonner les fluxsRépéter la liste de lectureRépéter la piste couranteRemplacer :Gain ReplayGain de l'AlbumPic ReplayGain de l'AlbumRéférence ReplayGain du BruitGain ReplayGain de la PistePic ReplayGain de la PisteÉtiquette ReplayGain à utiliser (se replier sur les autres au besoin) : Re-lit les données des pistes existantesRelire les méta-donnéesRebalayerReprendreRécupération des correspondances depuis le serveur...Révision :Bouton droitCopierCopier un CDEncoder le CD...Copie des pistes du CDDéplacer le curseur sur la chanson activeEmplacement racine :Modules activésRusse : Type de source :STEREOARRÊTConversion du taux d'échantillonage Type du Convertisseur du Taux d'ÉchantillonageTaux d'échantillonage :ÉchantillonsÉchantillons :Bac à sableEnregistrerSauvegarder toutes les listes de lectureSauvegarder toutes les discothèquesSauvegarder et quitterSauvegarder et restaurer la liste de lecture à l'extinction/démarrageSauvegarder la liste de lectureSauvegarder périodiquement la liste de lecture [min] :Sauvegarder la discothèqueAnalyse des fichiersRechercherRechercher dans : Rechercher dans la DiscothèqueRechercher dans la liste de lectureRechercher...SélectionerSélectionnez une police...Sélectionner toutSélectioner toutes les chansons de la liste de lecture (Faites un clic droit pour le menu)Sélectionnez le type de générationSélectioner des dossiersSélectioner des fichiersSélectioner le premier et fermer la fenêtreSélectionner le disque juke-boxAnnuler la sélectionFichiers sélectionnés :Envoyer vers le périphérique iFPSéparerSous-titre de la Partie de la CompilationChoisir la vitesse du lecteurPréférencesAfficher AqualungAfficher les valeurs RVAAfficher la piste active en grasAfficher un bouton de fermeture dans les ongletsMontrer seulement une miniature de la couverture pour les pistes dans la DiscothèqueMontrer les fichiers et les dossiers cachésMontrer le nom de la chanson dans le titre de la fenêtre principaleAfficher la taille du fichier dans la barre de statusMontrer l'onglet des étiquettes en premier dans la fenêtre d'information sur un fichierAfficher les durées des pistesMélanger les pistesVue simplifiée dans le configuration des filtres LADSPASimple canalTailleChanger d'apparenceSupport des thèmes, apparence, bidouilles de l'interface : Petites minuteries : LogicielChanson dans la liste de lecture : Informations sur la chanson : Titre de la chanson : Classe les artistes parClasse les albums parFichiers Audio (*.wav, *.aiff, *.au, ...)SourceFichier source :Démarrer minimiséBarre de status : Pente [dB/dB] :StéréoArrêter l'ajout des fichiersArrêter l'ajout de chansonsStructure :Longueur maximale du nom du sous-dossier:Soumettre le CD à la base de données CDDB..Soumettre un nouvel albumSoumettre cet album à la base de données CDDB...S'inscrire à un nouveau fluxSous-titreSuccèsSuédois : Zone de notificationSupport de la zone de notification Étiquetter les fichiers avec les méta-donnéesDate de l'ÉtiquettageÉtiquettes à ajouter lors de la création ou la mise à jour de fichiers MPEG audio :Dossier cible pour les fichiers rippésDossier cible :Fichier cible :TestL'adresse de courriel fournie pour la proposition est invalide.Les informations ci-dessous sont données par le lecteur, et ne reflètent pas forcément les véritables capacités du périphérique.Les fichiers sélectionnés vont être définitivement supprimés. Vous ne pourrez pas annuler cette opération. Voulez vous continuer ?La piste sélectionnée est dans un format qui n'est pas supporté par votre lecteur. Voulez vous continuer ?La discothèque sélectionnée a déjà été ajoutée dans la liste.La discothèque '%s' existe déjà. Ajouter la sur l'onglet Préférences/Discothèque.Il y a des changements en cours sur les meta-données du fichier.Ce binaire d'Aqualung est compilé avec :Ce CD ne contient pas d'information CD-Text.Ce bouton est deja affecté.Délai avant de considérer une connexion comme perdue :TitreFormat du TitreOrdre de Tri des TitresLe titre est entièrement en minuscules. Voulez vous continuer ?Le titre est entièrement en majuscules. Voulez vous continuer ?Titre :Afficher les filtres LADSPAAfficher la discothèqueAfficher la liste de lectureTotalNombre d'échantillonsTotal : PistePiste No.Commentaire de la pisteDurée de la pisteNom de la pisteNuméro de la pisteTitre de la pistePiste :PistesTraducteurs :Enlever les espaces en trop devant et derrièreType :URL :Ukrainien : Impossible d'ouvrir le fichierImpossible de supprimer %d fichier.Impossible de supprimer %d fichiers.Annuler la fermeture de l'ongletFin inattendue de la chaîne de caractères après '?'.Minimisation de toutes les fenêtres en même tempsInconnuAlbum inconnuArtiste inconnuAlbum inconnuPiste inconnueCaractère de conversion inconnu trouvé après '%%%%'.Caractère de conversion inconnu trouvé après '?'.Disque inconnuErreur inconnueToujours réessayer une lecture échouéeNon mesuréPistes non mesurées seulementInconnueSans titreMettre à jours tous les fluxsMettre à jour le fluxMettre à jour les méta-donnéesMettre à jour les méta-données...Mise à jour...Utiliser le nom du fichier seulement à la place du chemin entier en l'absence de méta-données.Utiliser une valeur manuel pour le RVA [dB]Utiliser des chemins relatifs dans la discothèqueUniquement utiliser la base de données localeChamps Définis par l'UtilisateurURL Définie par l'UtilisateurEncodage VBRVendeurVendeur :Vérifie l'intégrité des donnéesVersionRoue verticale de la souris :Nom visible :Niveau du volume :Me prévenir si le gestionnaire de fenêtre ne supporte pas la zone de notificationsAttentionWavPack Lors de l'ajout de nouveaux cadres, essayer d'initialiser leurs contenus avec le cadre d'une étiquette équivalente.Lorsque l'ordre de lecture est 'au hasard' les albums ajouté en mode 'Album' sont joués dans l'ordreWin32 Sound API Win32 Sound API Ce programme est un logiciel libre ; vous pouvez le redistribuer ou lemodifier suivant les termes de la “GNU General Public License” telle quepubliée par la Free Software Foundation : soit la version 2 de cettelicence, soit (à votre gré) toute version ultérieure. Ce programme est distribué dans l’espoir qu’il vous sera utile, mais SANSAUCUNE GARANTIE : sans même la garantie implicite de COMMERCIALISABILITÉni d’ADÉQUATION À UN OBJECTIF PARTICULIER. Consultez la Licence GénéralePublique GNU pour plus de détails . Vous devriez avoir reçu une copie de la Licence Générale Publique GNU avecce programme ; si ce n’est pas le cas, écrivez à Free Software Foundation,Inc., 675 Mass Ave, Cambridge, MA 02139, USA.Écrire un CD-RÉcrire un CD-RWÉcrire un DVD+RÉcrire un DVD+RWÉcrire un DVD-RÉcrire un DVD-RAMÉcrire un DVD-RWÉcriture en coursAnnéeAnnée :Vous devez fournir une adresse de courriels pour faire une proposition sur CDDBVous devez relancer Aqualung pour que les changements suivants prennent effet :_Annuler_Ajouter des fichiers..._Parcourir..._Configurer_Téléchargement_Envoisartisteartistesmeilleurbit doublebit flottantbit signébit non signéen train de compter...jourjourslecteurlecteursencodagerapidefluxfluxschamps :Gestionnaire de périphérique iFP (mode de téléchargement)Gestionnaire de périphérique iFP (mode d'envoi)Support du pilote iRiver iFP élémentélémentsnouvel élémentnouveaux élémentsralbumalbumsRacine / Artiste / Artiste / Artiste/ Album / PisteRacine / Artiste / Artiste / Album / PisteRacine / Artiste / Album / PisteRacine / Album / Pisterwsecondessndfile (WAV) sndfile (WAV, AIFF, etc.) sndio Audio étiquette :pistepistesinjoignableUtiliser la largeur de la fenêtre de navigationaqualung-0.9beta11/src/po/hu.mo0000644000175000001440000021553611331334313013277 00000000000000$,<8P9P4UPP/Q+MRFyT2U5V)X[X >ZIZRZhZ ~ZZZZZZZ ZZO[T[[[b[ i[ t[[[ [[ [[ [ [ [ [ \ \\3\J\b\t\\ \\\\ \\\\\\] ] !] ,]6]>]&X] ] ]9] ]]]^(^&B^ i^^^^^^^_'_E_^_d_ u_4____ __ _ _`A`A]` `/``hapbbb>b>b $c0c Hc(Uc~cc(ccRc$d -d 8dCdLd$hdRd!d&e")eLege}eeee e eeee e;f H S ] h s  Ð֐ ((>.g  ̑  Ò˒   , : G T _ m y $͓ G* r  ͔ޔ'E[4qҕ! 7 ANR Ycu  ɖ  (-@P-_ ! ȗח ޗ % 6@A И  *: CQa02ʙ) '+Ht #Ț ͚&ښ , 8EU&e  Лכܛ  +I![} ǜ ߜ7!$F Xe5jj Q7F/`&-  Ģ=բ=QXt ģ ң  * KQ Vbv#ޤ  .5<2r ,  % 6BW oC{ ٦( 9FMUks :V ?b ʨ ֨  9KW é Ωة  !-16<CLQV\"c ªǪͪ ֪0'"Ji ƫ̫ ӫ߫,&%*Lw?]l+k\+ն  - DRY`#z øѸ\׸4;B I Ub!~ Źҹ ڹ $=Uo  ºк   $& KWm'4̻>.m0Ӽ%2.Ix+ؽ  :@*{ 3Ǿ %<K[=z? 27qu 9$:^  3 & DWQ &<V:37)"'Jh V(m =3&I(p ''9*a &D5z  &'Nf y+  :Ugo+v  #4Xo $""6 YcVt9# ) 3=)Z9  =']) 16h q{B=)JF*#,Pa fr '50LE4.c0b)DSZl~' 4Ja{+2)\{)1%D)`( .A3u'!*9Xr% @ MDWD-w    /: AK ]h ~ 1B? "!   -9PW_hq)"%+16 ; HT]et27Nm/    !'Bj }&* :)dl"Kbk} $' @L R \ gs 5##: Tb%~/!4)T/~ #'&Fm} % (GW^d l'x  ## GQbv   *)#T x g W[o !#8 \g yhLe,x  ")1F O Y&e ='>G Z ht$MDT(r*"&DI#.62BK#*"."/.R 34#+O We z# A N;\  5 JT3X  -> M[s<<86ox~ ! *   '5D]s$ %7L3j!PB[q %2 Hi9)% ? J'U }     $./)^  F/v1 ( G SavO'"59o!':+X B87!1Y7/ )7>+O{  *(&%LTc |  $$ A 'X         P .Y    3 w U S .A [p 9 ; /B  r  5O Tb4q5  4@ FS c q }  =#!#Ei""  /,LyR   #-J_wP 7*Kv   E&l|kLM ^ k y 0RWf   & !@TX \ f p|$%!   &(.94.n#  $*0?RY_sS?3V2(\J""`!${C 8{-'&V5/%.sa,-PUK 5~q B}LwwrUHY{X1z#(k eP*H@g8=b|k?cs[f*S,^o2B+B StD?h tx|~&yvdx=(Fk]>; U&GTe\ +k 64%4WoZP_|: mDCJ< ;!>lN/Dy^dJZ*^#:@m81dFp9_p`76OlLgv}n)GRidYbFha!B l|'5 # yMaO\Qft}v@/c3 08 ;{Nz1rXOP^bTW7\]LWCa:c@NDu"]MnRE`xhre(rZEo/6ijK'X<wp~.Lg:OjJ2F?.5.jVE`TX1f>pmQ"= A9zV)UA~<$qH3[jnE%Z GG,Y06u+ sQ4+&; $K[$q*3'Sz_i< -Q9 wIMA=l}gI02#n)yqfmIb]TMWK%i u,!A)CN9vo7Ic4-u>hteHR[ x70 Maximum number of retries: Destination directory is not read-write accessible! Here you should enter a comma-separated list of domains that should be accessed without using the proxy set above. Example: localhost, .localdomain, .my.domain.com Most drives let Aqualung know when a CD has been inserted or removed by providing a 'media changed' flag. However, some drives don't set this flag properly, and thus it may happen that a newly inserted CD remains unnoticed to Aqualung. In such cases, enabling this option should help. Set the drive speed for CD playing in CD-ROM speed units. One speed unit equals to 176 kBps raw data reading speed. Warning: not all drives honor this setting. Lower speed usually means less drive noise. However, when using Paranoia error correction modes for increased accuracy, generally much larger speeds are required to prevent buffer underruns (and thus audible drop-outs). Please note that these settings do not apply to CD Ripping, which always happens with maximum available speed and with error correction modes manually set before every run. The Music Store you selected has a matching Artist and Album, already containing some tracks. If you press OK, these tracks will be removed. The files themselves will be left intact, but they will be removed from the destination Music Store. Press Cancel to get back to change the Artist/Album or the destination Music Store. The file you enter/choose here will set the Lua program to use to format the title. See the Aqualung manual for details. Here is a quick example of what you can use in the file: function playlist_title() return m('artist') .. '-' .. m('title') .. ' (' .. m('album') .. ') (' .. i('filename') .. ')' end The string you enter here will be parsed as a command line before parsing the actual command line parameters. What you enter here will act as a default setting and may or may not be overridden from the 'real' command line. Example: enter '-o alsa -R' below to use ALSA output running realtime as a default. The template string you enter here will be used to construct a single title line from an Artist, a Record and a Track name. These are denoted by %%%%a, %%%%r and %%%%t, respectively. The template string you enter here will be used to construct the filename of the exported files. The Artist, Record and Track names are denoted by %%%%a, %%%%r and %%%%t. The track number and format-dependent file extension are denoted by %%%%n and %%%%x, respectively. The flag %%%%i gives an identifier which is unique within an export session. (%.1f MB) (%d/%d) (capacity = %.1f MB) Free space (%.1f MB) Selected: out L out R% of standard deviation% of standard deviation :%.1f MB / %.1f MB%d / %d directories%d / %d files%d dB%d of %d songs have format unsupported by your player. Do you want to proceed?%d%% L%d%% R%ld Hz(Untitled)(audio only)(choose a category)(error loading image)(no comment)(no description)(no image)(none)*File info*Music Store100 pixels200 pixels300 pixels50 pixelsDevice statusLocal directoryRemote directorySongs infoTransfer progressA large, coloured fishALSA Audio APEAbortAbort ongoing updateAborted...AboutAbstractAccessAction:Active song in playlist: AddAdd ArtistAdd RecordAdd TrackAdd URLAdd all items to playlistAdd all items to playlist (Album mode)Add directoryAdd filesAdd files to playlist (Press right mouse button for menu)Add item...Add mouse button commandAdd new artist to this store...Add new artist...Add new items to playlistAdd new items to playlist (Album mode)Add new record to this artist...Add new record...Add new track to this record...Add new track...Add to CommentsAdd to Music StoreAdd to playlistAdd to playlist (Album mode)Add year to the comments of new recordsAdding files to PlaylistAlbumAlbum Sort OrderAlbum imageAlbum mode is the default when adding entire recordsAlbum:AllAll Audio FilesAll FilesAll Playlist FilesAll tracksAll wordsAlways show the tab barAn error occurred while attempting to connect to the CDDB server.An error occurred while submitting the record to the CDDB server.AppearanceApply averaged RVA to tracks of the same recordAqualung is compiled with system tray support, but the status icon could not be embedded in the notification area. Your desktop may not have support for a system tray, or it has not been configured correctly.Aqualung is compiled without LADSPA plugin support. See the About box and the documentation for details.Aqualung is compiled without Sample Rate Converter support. See the About box and the documentation for details.Aqualung playlist (*.xml)ArtistArtist appears to be in all lowercase. Do you want to proceed?Artist appears to be in all uppercase. Do you want to proceed?Artist nameArtist name (lowercase)Artist namesArtist/Album already existing, not emptyArtist/performerArtist:Ask for confirmation when removing itemsAttached PictureAttached Picture frame with no image set! Please set an image or remove the frame.Audio CDAudio dataAudiophileAuthors:Auto-check interval [hour]:Auto-create tracks from these files:Automatic update has been disabled for all feeds in the Podcasts store popup menu.Automatically add CDs to PlaylistAutomatically remove CDs from PlaylistAutomatically roll to active trackAutomatically update feedsAvailable connectionsAvailable pluginsAvailable skinsAverageBPMBack coverBalance: %sBand/OrchestraBand/artist logotypeBand/orchestraBandwidth:Batch update & encode (mass tagger, CD ripper, file export)Batch-update file metadata...BatteryBeginBibliographyBig timer: Binary ObjectBitrate [kbps]:BrowseBuild / Update store from filesystem...Build version: Build/Update storeBuilding store from filesystemBurn ProofButtonCC2 Error CorrectionCD AudioCD drive speed:CDDA (Audio CD) support CDDBCDDB (not available)CDDB lookupCDDB queryCDDB query for this CD...CDDB query for this record...CDDB server:CDDB support CDDBP (port 888)Calculate RVACalculate volumeCalculate volume (recursive)Calculating volume levelCannot write to selected directory. Please select another directory.CapitalizationCapitalize: Case sensitiveCatalog NumberCategoryCategory:ChangeChange balanceChange current songChange song positionChange volumeChannel count:Channels:Clear connectionsClear listClick here to set mouse buttonCloseClose other tabsClose tabClose trayClose window when completeClose window when transfer completeCollapse all itemsColorsColumnCombine play and pause buttonsCommandCommentCommentsComments:Commercial InformationComposerCompressed modules (*.bz2)Compressed modules (*.gz)Compressed modules (*.gz, *.bz2)Compression level:Compression: Extra HighCompression: FastCompression: HighCompression: InsaneCompression: NormalConductorConnect via HTTP proxyConnecting to CDDB server...Connection timeout [sec]:ContactContent GroupConversion error in field %s: '%s' does not conform to format '%s'!Conversion to target charset failedConvert underscore to spaceCopyCopyrightCopyright/Legal InformationCore design, engineering & programming: Correct existing recordCould not load image from: %sCover artCreate a new directoryCreate directoryCreate empty storeCreate empty store...Create subdirectories for albumsCreate subdirectories for artistsCurrent file: Cut selectedDSPDateDebut AlbumDecoding support:Default cover width:Delete downloaded items from the filesystemDescriptionDescription:DestinationDetect media changeDevice is busy. (Aqualung was unable to claim its interface.)Device is not responding. Try jiggling the handle.Device path:Direct connection to the InternetDirectory '%s' will be removed with its entire contents. Do you want to proceed?Directory drivenDirectory nameDirectory name (lowercase)Directory structureDisable all pluginsDisable control buttons reliefDisable manual ejectDisable skin supportDiscDisc infoDisc info...Discard changesDo not closeDo not exitDo not magnify images with smaller widthDo not reencode files matching wildcard:Do not reencode files already being in the target formatDo nothingDo you want to save store "%s" before removing from Music Store?Do you want to save the store before removing?Don't show cover thumbnail in the main windowDoneDownload directory:Downloading %d/%d (%d%%) ...Drag and drop entries in the list to set the feed order in the Music Store.Drag and drop entries in the list below to set the column order in the Playlist.Drive infoDrive info...Drop statistical aberrations based onDual channelDuration:During performanceDuring recordingEAN/UPCEdit ArtistEdit RecordEdit StoreEdit TrackEdit artist...Edit feedEdit feed settingsEdit item...Edit record...Edit store...Edit track...EjectEmail address for submission:Embed playlist into main windowEmphasis:Emphasis: noneEmphasis: reservedEnable Music Store tree node iconsEnable all pluginsEnable playback RVAEnable rules hintEnable statusbarEnable statusbar in Music StoreEnable statusbar in playlistEnable systrayEnable toolbarEnable toolbar in Music StoreEnable tooltipsEnable tree node iconsEnabledEncoded byEncoding TimeEncoding support:Enqueue playlistErrorError converting field %s to Year: '%s' is not an integer number!Error in format stringError in title format stringExact matches onlyExclude files matching wildcardExpand Stores on startupExpected '}' after '{', but end of string found.Export all items...Export artist...Export filesExport item...Export new items...Export record...Export store...Export track...Exporting filesExtended Title Format Files (*.lua)Extended data:FLAC PicturesFailed to set metadata for the following files:Failed to write metadata to file. Reason: %sFileFile "%s" does not exist or your write permission has been withdrawn. Check if the partition containing the store file has been unmounted.File '%s' will be removed. Do you want to proceed?File OwnerFile TypeFile format:File icon (32x32 PNG)File icon (other)File infoFile info...File is not writableFile name: File:FilenameFilename template:Filename:Files selected for removalFilesystemFilterFirst word onlyFollows the directory structure to identify the artists and records. The files are added on a record basis.FontsForce TOC re-read on every drive scanForce case: Force other letters to lowercaseFormatFormat:Free Lossless Audio Codec (*.flac)Free Lossless Audio Codec (FLAC) Free spaceFrench: Front coverGeneralGeneric StreamMetaGenreGenre:German: Graphics:HTTP (port 80)Hard reset deviceHelpHide AqualungHide comment paneHide the Music Store comment paneHomepage:Horizontal mouse wheel:Hungarian: IDID3v1ID3v2ISBNISRCIcy-DescriptionIcy-GenreIcy-NameIdleIllustrationImplicit command lineImport Comment tagImport Replaygain tag as manual RVAImport as ArtistImport as RVAImport as RecordImport as Sort KeyImport as TitleImport as Track No.Import as YearIn any caseInclude only files matching wildcardIndependentIndexInitial keyInputsInstrumentsInstruments:Internal errorInternetInternet Radio Station NameInternet Radio Station OwnerInterpreted/RemixedIntroplayInvalid 'Genre' field valueInvalid 'Track no.' field valueInvert current stateInvert selectionInvolved PeopleIt is very likely that the year is wrong. Do you want to proceed?Italian: JACK Audio Server JACK Port SetupJACK connection lostJACK has either been shutdown or it disconnected Aqualung because it was not fast enough. All you can do now is restart both JACK and Aqualung.JACK port setupJapanese: Joint stereoKeep main window always on topKey: LADSPA patch builderLADSPA plugin processingLADSPA plugin support LAME (MP3) LAVC (AC3, AAC, WavPack, WMA, etc.) LAVC audio/video filesLabel CodeLanguageLayer ILayer IILayer IIILead artist/performerLeaflet pageLeft and right mouse buttons are reserved.Left buttonLengthLength:LicenseLimitsLinear threshold [dB]Linear threshold [dB] :Listening environment:Living roomLoad playlistLoad playlist in new tabLoad settings from Music Store fileLocal CDDB directory:LocationLocation and filenameLogo, icons: Loop playback support Loop range: %d-%d%%Loop range: %d-%d%% [%s - %s]Lua (programmable title formatting) support Lyricist/Text WriterLyricist/text writerMIME type: %sMOD Audio (MOD, S3M, XM, IT, etc.) MONOMP3 Playlist (*.m3u)MPEG Audio (*.mp3, *.mpa, *.mpega, ...)MPEG Audio (MPEG 1-2.5 Layer I-III) MPEG StreamMetaMain windowMatches:Maximum number of items:Maximum number of retries:Maximum space to use [MB]:MediaMemory allocation errorMetadataMetadata editor (File info dialog)Middle buttonMiscellaneousMode:Model:Module infoModules (*.xm, *.mod, *.it, *.s3m, ...)Monkey's Audio Codec Monkey's Audio Codec (*.ape)MoodMount RainierMouse buttonMouse buttonsMouse wheelMovie/video screen captureMultimedia Playlist (*.pls)Musepack Musepack (*.mpc)Musepack ReplayGainMusic StoreMusic Store Files (*.xml)Music Store: Musician CreditsMuteNULLNameName to sort by:Name transformationName:New tabNextNext songNo discNo matching record found.No metadata support for this formatNo outputNo proxy for:No suitable iRiver iFP device found. Perhaps it is unplugged or turned off.No.Noisy workshopNoneNone of the selected songs has format supported by your player. Do you want to proceed?Note: pre-existing tags will be updated even though they might not be checked here.OSS Audio OfficeOfficial Artist WebsiteOfficial Audio File WebsiteOfficial Audio Source WebsiteOfficial Radio Station WebsiteOgg Speex Ogg Speex (*.spx)Ogg Vorbis Ogg Vorbis (*.ogg)Ogg Xiph CommentsOne or more stores in Music Store have been modified. Do you want to save them before exiting?One song has format unsupported by your player. Do you want to proceed?Only if unmeasuredOpenBSD compatibility, metadata tweaks: Optional features:OrganizationOriginal AlbumOriginal ArtistOriginal FilenameOriginal LyricistOriginal Release TimeOtherOutputOutput driver support:Output:OutputsOverall: Override skin settingsParanoiaParanoia error correctionPart Of A SetPathPaths must either be absolute or starting with a tilde, which will be expanded to the user's home directory. Drag and drop entries in the list to set the store order in the Music Store.Paths must either be absolute or starting with a tilde.Paths to Music Store databasesPatterns:PausePaymentPerform overlapped readsPerformerPerformer Sort OrderPicture type:PlayPlay CD AudioPlay/PausePlay/Pause songPlay/Stop songPlayback RVAPlayback RVA is currently disabled. Do you want to enable it now?PlaylistPlaylist DelayPlaylist column orderPlaylist: Please enter a new name.Please enter directory name.Please select a Music Store database.Please select a Programable Title Format File.Please select a local path.Please select at least one valid song from playlist.Please select the audio file for this track.Please select the audio files for this record.Please select the directory for exported files.Please select the directory for ripped files.Please select the download directory for this podcast.Please select the root directory.Please select the xml file for this store.Please specify the file to load the image from.Please specify the file to load the playlist from.Please specify the file to save the image to.Please specify the file to save the playlist to.Podcast URL:Podcast support PodcastsPort:Position: %d%%Post Fader (after Volume & Balance)Pre Fader (before Volume & Balance)Predefined transformationsPreviousPrevious songProcessing metadataProcessing:ProducedProfile: BraindeadProfile: InsaneProfile: RadioProfile: StandardProfile: TelephoneProfile: ThumbProfile: XtremeProgrammable title format fileProgramming, GUI engineering: ProgressProgress:Protocol for querying (direct connection only):Proxy host:Proxy settingsPublication RightPublisherPublisher's Official WebsitePublisher/studio logotypePulseAudio Put control buttons at the bottom of playlistQuitRVARVA for Unmeasured Files [dB] :RVA valuesRead CD+GRead CD-DARead CD-RRead CD-RWRead DVD+RRead DVD+RWRead DVD-RRead DVD-RAMRead DVD-ROMRead DVD-RWRead ISRCRead MCNRead Mode 2 Form 1Read Mode 2 Form 2Read multiple sessionsReadingReading fileReally remove "%s" from the Music Store?Really remove '%s' from the Music Store?Really remove store "%s" from the Music Store?ReasonRecordRecord DateRecord LocationRecord nameRecord name (lowercase)Record titlesRecording location/studioRecursive search from the root directory for audio files. The files are processed independently, so only metadata and filename transformation are available.Reference volume [dBFS] :RefreshRegexp matches empty stringRegexp:Regular expressionRelatedRelease TimeRemoveRemove ArtistRemove RecordRemove StoreRemove TrackRemove allRemove artistRemove deadRemove feedRemove file extensionRemove filesRemove item...Remove leading numberRemove non-existing files from storeRemove older items [day]:Remove recordRemove selectedRemove selected songs from playlist (Press right mouse button for menu)Remove storeRemove trackRemoving non-existing filesRenameRename playlistReorder feedsRepeat all songsRepeat current songReplace:ReplayGain Album GainReplayGain Album PeakReplayGain Reference LoudnessReplayGain Track GainReplayGain Track PeakReplayGain tag to use (with fallback to the other): Replaygain_album_gainReplaygain_track_gainReread data for existing tracksReread file metadataRescanResumeRetrieving matches from server...Revision:Right buttonRipRip CDRip CD...Ripping CD tracksRoll to active songRoot path:Running pluginsRussian: SRC Type: STEREOSTOPPINGSample Rate Converter support Sample Rate Converter typeSamplerate:SamplesSamples:SandboxSaveSave all playlistsSave all storesSave and closeSave and restore the playlist on exit/startupSave playlistSave playlist periodically [min]:Save storeScanning filesSearchSearch in:Search the Music StoreSearch the PlaylistSearch...SelectSelect a font...Select allSelect all songs in playlist (Press right mouse button for menu)Select build typeSelect directorySelect filesSelect first and close windowSelect juke-box discSelect noneSelected files:Send to iFP deviceSeparateSet SubtitleSet drive speedSettingsShow AqualungShow RVA valuesShow active track name in boldShow close button in tabShow cover thumbnail for Music Store tracks onlyShow hidden files and directories in file choosersShow song name in the main window's titleShow soundfile size in statusbarShow tags tab first in the file info dialogShow track lengthsShuffle songsSimple view in LADSPA patch builderSingle channelSizeSkin chooserSkin support, look & feel, GUI hacks: Small timers: SoftwareSong in playlist: Song info: Song title: Sort artists bySort records bySound Files (*.wav, *.aiff, *.au, ...)SourceSource file:Start minimizedStatusbar: Steepness [dB/dB] :StereoStopStop adding filesStop adding songsStructure:Subdirectory name length limit:Submit CD to CDDB database...Submit new recordSubmit record to CDDB database...Subscribe to new feedSubtitleSuccessSwedish: SystraySystray support Tag files with metadataTagging TimeTags to add when creating or updating MPEG audio files:Target directory for ripped filesTarget directory:Target file:TestThe email address provided for submission is invalid.The information below is reported by the drive, and may not reflect the actual capabilities of the device.The selected files will be deleted from the filesystem. No recovery will be possible after this operation. Do you want to proceed?The selected song has format unsupported by your player. Do you want to proceed?The specified store has already been added to the list.The store '%s' already exists. Add it on the Settings/Music Store tab.There are unsaved changes to the file metadata.This Aqualung binary is compiled with:This CD does not contain CD-Text information.This button is already assigned.This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.Timeout for socket I/O:TitleTitle FormatTitle Sort OrderTitle appears to be in all lowercase. Do you want to proceed?Title appears to be in all uppercase. Do you want to proceed?Title:Toggle LADSPA patch builderToggle music storeToggle playlistTotalTotal samples:Total: TrackTrack No.Track commentTrack lengthsTrack nameTrack numberTrack titlesTrack:TracksTranslators:Trim leading, tailing and duplicate spacesType:URL:Ukrainian: Unable to open fileUnable to remove %d file.Unable to remove %d files.Undo close tabUnexpected end of string after '?'.United windows minimizationUnknownUnknown AlbumUnknown ArtistUnknown RecordUnknown TrackUnknown conversion type character found after '%%%%'.Unknown conversion type character found after '?'.Unknown discUnknown errorUnlimited retry on failed reads (never skip)UnmeasuredUnmeasured tracks onlyUnrecognizedUntitledUpdate all feedsUpdate feedUpdate file metadataUpdate file metadata...Updating...Use basename only instead of full path if no metadata is available.Use manual RVA value [dB]Use relative paths in store fileUse the local database onlyUser Defined TextUser Defined URLVBR encodingVendorVendor:Verify data integrityVersionVertical mouse wheel:Visible name:Volume level:Volume: %sWarn me if the Window Manager does not support system trayWarningWavPack WavPack (*.wv)When adding new frames, try to set their contents from another tag's equivalent frame.When shuffling, records added in Album mode are played in orderWin32 Sound API Write CD-RWrite CD-RWWrite DVD+RWrite DVD+RWWrite DVD-RWrite DVD-RAMWrite DVD-RWWritingYearYear:You have to provide an email address for CDDB submission.You will need to restart Aqualung for the following changes to take effect:_Abort_Add files..._Browse..._Configure_Download_Uploadartistartistsbestbit doublebit floatbit signedbit unsignedcounting...daydaysdrivedrivesencodingfastfeedfeedsfield:iFP device manager (download mode)iFP device manager (upload mode)iRiver iFP driver support itemitemsnew itemnew itemsrrecordrecordsroot / artist / artist / artist / record / trackroot / artist / artist / record / trackroot / artist / record / trackroot / record / trackrwsecondssndfile (WAV) sndfile (WAV, AIFF, etc.) sndio Audio tag:tracktracksunreachableuse browser window widthReport-Msgid-Bugs-To: POT-Creation-Date: 2010-01-13 00:15+0100 PO-Revision-Date: 2010-01-13 00:16+0100 Last-Translator: Peter Szilagyi MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=1; plural=0; Újrapróbálások maximális száma: A célkönyvtár nem írható-olvasható! Azon domainek vesszővel elválasztott felsorolása, amelyek eléréséhez ne használja a fent beállított proxyt. Példa: localhost, .localdomain, .my.domain.com A legtöbb meghajtó egy 'media changed' jelzőn keresztül értesítést küld egy CD berakásáról vagy kivételéről. Néhány meghajtó viszont nem használja megfelelően ezt a jelzőt, ezért előfordulhat, hogy egy újonnan betett CD észrevétlen marad. Ilyen esetekben segíthet ezen opció engedélyezése. CD lejátszás sebességének beállítása CD-ROM sebesség egységekben. Egy egység megfelel 176 kBps nyers adat olvasási sebességnek. Figyelmeztetés: nem minden meghajtó veszi figyelembe ezt a beállítást. Kisebb sebesség általában alacsonyabb zajt eredményez. Viszont a nagyobb pontosság érdekében használható Paranoia hibajavítás sokszor magasabb sebességet követel, hogy elejét vegye a buffer kiürülésének (és ezáltal a hallható kihagyásoknak). Fontos, hogy ezek a beállítások nem vonatkoznak a CD rippelésre, ami mindig a lehető legnagyobb sebességgel történik. A hibajavítás külön beállítható minden rippelés előtt. A kiválasztott tárolóban már van ilyen előadó és album, amely néhány számot is tartalmaz. Az OK gombot megnyomva ezek a számok eltűnnek a tárolóból. Ez maguk a fájlokat nem érinti, csak a célként megjelölt tárolóból törlődnek. Ha inkább szeretnél visszatérni a előadó, album vagy zenetár módosításához, válaszd a Mégse gombot. Az alábbi fájl a címek formázását írja elő a Lua program számára. A funkció részletes leírása a manualban olvasható. Egy rövid példa a fájl tartalmára: function playlist_title() return m('artist') .. '-' .. m('title') .. ' (' .. m('album') .. ') (' .. i('filename') .. ')' end Az alábbi szöveget a program parancssorként értelmezi, az aktuális parancssor feldolgozása előtt. Az ide írt kapcsolók alapértelmezett beállításokként működnek, amelyeket a valódi parancssori paraméterek felülbírálhatnak. Például a '-o alsa -R' az ALSA kimenet valós idejű használatát írja elő alapértelmezettként. Az alábbi sablon az előadó nevéből, valamint a lemez- és számcímekből összeállított címsor formátumát adja meg. A %%%%a, %%%%r és %%%%t vezérlők rendre az előadót, a lemezt és a szám címét jelölik. Az alábbi sablon az exportált fájlok nevét határozza meg. Az előadó, lemez és szám címeket %%%%a, %%%%r és %%%%t jelöli. A track számát és a formátumtól függő kiterjesztést %%%%n és %%%%x adja meg. Az %%%%i kapcsoló az export folyamaton belül egyedi azonosítót eredményez. (%.1f MB) (%d/%d) (kapacitás = %.1f MB) Szabad hely (%.1f MB) Kijelölve: out L out Ra szórás megadott %-ánMax. eltérés a szórás %-ában :%.1f MB / %.1f MB%d / %d könyvtár%d / %d fájl%d dBA lejátszód %d szám formátumát nem támogatja a megadott %d közül. Akarod folytatni?%d%% L%d%% R%ld Hz(Névtelen)(csak audio)(válassz egy kategóriát)(hiba a kép betöltése közben)(nincs megjegyzés)(nincs leírás)(nincs kép)(nincs)*Fájl infó*Zenetár100 képpont200 képpont300 képpont50 képpontEszköz állapotaHelyi könyvtárTávoli könyvtárSzám infoMásolási folyamatEgy nagy, színes halALSA Audio APEMegszakításFrissítés megszakításaMegszakítva...NévjegyAbsztraktHozzáférésMűvelet:Aktív szám a Lejátszólistában: HozzáadásElőadó hozzáadásaAlbum hozzáadásaSzám hozzáadásaURL hozzáadásaÖsszes elem lejátszólistához adásaÖsszes elem lejátszólistához adása (Album mód)Könyvtár hozzáadásaFájlok hozzáadásaFájlok hozzáadása a listához (jobb egérgomb: helyi menü)Elem hozzáadása...Egérgomb funckió hozzáadásaÚj előadó hozzáadása ehhez a tárolóhoz...Új előadó hozzáadása...Új elemek lejátszólistához adásaÚj elemek lejátszólistához adása (Album mód)Új album hozzáadása ehhez az előadóhoz...Új album hozzáadása...Új szám hozzáadása ehhez az albumhoz...Új szám hozzáadása...Hozzáadás a kommentekhezHozzáadás a ZenetárhozLejátszólistábaLejátszólistába (Album mód)Év hozzáadása az újonnan felvett albumok kommentjéhezFájlok hozzáadása a LejátszólistáhozLemezAlbum sorrendjeAlbum képLemezek alapértelmezett hozzáadása album módbanLemez:MindMinden hangfájlMinden fájlMinden lejátszólistaMinden számraMinden szónálMindig látszódjanak a fülekHiba történt a CDDB szerverhez való kapcsolódás közben.Hiba történt a lemez CDDB szerverhez való küldése közben.MegjelenésEgyazon lemez számaira átlagolt RVA alkalmazásaAz Aqualung támogatja a rendszertálca használatát, de az állapotikont nem sikerült a tálcára helyezni. Lehet, hogy az asztalodról hiányzik a rendszertálca, vagy nincs megfelelően beállítva.Az Aqualungot LADSPA plugin támogatás nélkül fordították. Részletek a Névjegyben és a dokumentációban.Az Aqualungot mintavételi frekvencia konverter támogatás nélkül fordították. Részletek a Névjegyben és a dokumentációban.Aqualung lejátszólista (*.xml)SzerzőAz előadó csupa kisbetűvel szerepel. Akarod folytatni?Az előadó csupa nagybetűvel szerepel. Akarod folytatni?Előadó neveElőadó neve (kisbetűvel)ElőadókAz előadó vagy album már létezik, és nem üresMűvész/előadóElőadó:Megerősítés elemek törlése előttCsatolt képAz Attached Picture keretből hiányzik a kép. Adj meg egyet, vagy töröld a keretet.Audio CDAudio jellemzőkAudiofilSzerzők:Automatikus ellenőrzés ideje [óra]:Számok automatikus létrehozása a következő fájlokból:A források automatikus frissítése ki van kapcsolva a Podcasts tároló menüjében.CD-k automatikus hozzáadása a LejátszólistáhozCD-k automatikus eltávolítása a LejátszólistábólAutomatikus görgetés az aktív számhozForrások automatikus frissítéseElérhető összeköttetésekRendelkezésre álló effektekElérhető szkinekÁtlagosBPMHátsó borítóBalansz: %sZenekar/orchestraZenekar/előadó logótípusZenekar/orchestraSávszélesség:Frissítés a háttérben & kódolás (taggelés, CD rippelés, fájlok exportálása)Metaadatok frissítése a háttérben...ElemKezdetIrodalomjegyzékNagy időkijelző: Bináris objektumBitráta [kbps]:TallózásTároló felépítése / aktualizálása fájlrendszerről...Fordítási verzió: Tároló felépítése/aktualizálásaTároló felépítése fájlrendszerrőlBurn ProofGombCC2 hibajavításCD AudioCD meghajtó sebesség:CDDA (Audio CD) támogatás CDDBCDDB (nem elérhető)CDDB lekérdezésCDDB lekérdezésCD lekérdezése CDDB adatbázisból...Album lekérdezése CDDB adatbázisból...CDDB szerver:CDDB támogatás CDDBP (port 888)Hangosság meghatározásaHangosság meghatározásaHangosság meghatározása (rekurzív)Hangosság meghatározásaA kiválasztott könyvtárba nem lehet írni, válassz egy másikat.Kis/nagybetű beállításaNagy kezdőbetű:Kis/nagybetűk különböznekKatalógus számKategóriaKategória:CsereBalansz változtatásaAktuális szám léptetéseSzámon belül pozíció változtatásHangerő változtatásaCsatornák száma:Csatornák:Összeköttetések törléseLista törléseKattints ide az egérgomb beállításáhozBezárásTöbbi lap bezárásaLap bezárásaTálca behúzásaAblak bezárása, ha készAblak bezárása, ha készElemek bezárásaSzínekOszlopLejátszás és szünet gombok egyesítéseParancsMegjegyzésMegjegyzésekMegjegyzések:Kereskedelmi információZeneszerzőTömörített modulok (*.bz2)Tömörített modulok (*.gz)Tömörített modulok (*.gz, *.bz2)Tömörítés szintje:Tömörítés: Extra magasTömörítés: GyorsTömörítés: MagasTömörítés: ElmebetegTömörítés: NormálKarmesterCsatlakozás HTTP proxy-n keresztülKapcsolódás a CDDB szerverhez...Kapcsolódás időkorlátja [sec]:KapcsolatTartalom csoportKonverziós hiba a következő mezőben: %s '%s' nem felel meg a(z) '%s' formátumnak.Nem sikerült konvertálni a megadott karakterkészletre.Aláhúzás szóközzé alakításaMásolásCopyrightCopyright/Legal információArchitektúra, tervezés & programozás: Meglévő album módosításaAz alábbi helyről nem sikerült képet betölteni: "%s"LemezborítóÚj könyvtár létrehozásaKönyvtár létrehozásaÜres tároló létrehozásaÜres tároló létrehozása...Alkönyvtár létrehozása lemezenkéntAlkönyvtár létrehozása előadónkéntAktuális fájl: Kijelölt elemek megtartásaDSPDátumDebütáló lemezDekódolás támogatása:Alapértelmezett borítóméret:Letöltött adások törlése a fájlrendszerrőlLeírásLeírás:CélLemezcsere érzékeléseAz eszköz foglalt. (Nem sikerült hozzáférni az interfészhez.)Az eszköz nem válaszol. Próbáld mozgatni a fogantyúját.Elérési út:Közvetlen InternetkapcsolatBiztosan el akarod távolítani a '%s' könyvtárat és teljes tartalmát?Könyvtár alapúKönyvtár neveKönyvtár neve (kisbetűvel)Könyvtár struktúraÖsszes effekt letiltásaVezérlőgombok kiemelkedésének tiltásaTálca kézi kitolásának tiltásaSzkinek tiltásaDiscLemez infóLemez infó...Változások eldobásaNe zárja beNe lépjen kiA kisebb képeket ne nagyítsaMintára illeszkedő fájlok kihagyásaA célformátumban lévő fájlokat ne kódolja újraNe csináljon semmitEl akarod menteni a(z) "%s" tárolót mielőtt eltávolítod a Zenetárból?El akarod menteni a tárolót eltávolítás előtt?Ne jelenjen meg a borító képe a főablakbanKészLetöltési könyvtár:Letöltés %d/%d (%d%%) ...Az alábbi lista elemeinek átrendezésével állítható a Zenetárban lévő források sorrendje.Az alábbi lista elemeinek átrendezésével állítható a Lejátszólista oszlopainak sorrendje.Meghajtó infóMeghajtó infó...Beszámítás az átlagba, ha belül van:KétcsatornásHossz:Előadás közbenFelvétel közbenEAN/UPCElőadó szerkesztéseAlbum szerkesztéseTároló szerkesztéseSzám szerkesztéseElőadó szerkesztése...Forrás szerkesztéseForrás beállításainak szerkesztéseElem szerkesztése...Album szerkesztése...Tároló szerkesztése...Szám szerkesztése...Tálca kitolásaEmail cím feltöltéshez:A Lejátszólista beágyazása a főablakbaElőkiemelés:Előkiemelés: nincsElőkiemelés: fenntartottIkonok engedélyezése a Zenetár csomópontjaibanÖsszes effekt engedélyezéseLejátszáskori RVA használataSorok vonalazásaÁllapotsor engedélyezéseÁllapotsor engedélyezése a ZenetárbanÁllapotsor engedélyezése a LejátszólistábanRendszertálca engedélyezéseEszköztár engedélyezéseEszköztár engedélyezése a ZenetárbanBuboréksúgók engedélyezéseIkonok engedélyezése a csomópontokbanÉrvényesKódolóKódolás idejeKódolás támogatása:Lejátszólista hozzáfűzéseHibaA(z) '%s' mező nem konvertálható évre: '%s' nem egész szám.Hiba a formátum sablonbanHiba a címformátum sablonbanCsak teljes egyezésMintára illeszkedő fájlok kihagyásaTárolók lenyitása indításkorA sablonban hiányzik a '}' végzárójel.Összes adás exportálása...Előadó exportálása...Fájlok exportálásaAdás exportálása...Új adások exportálása...Album exportálása...Tároló exportálása...Szám exportálása...Fájlok exportálásaCímformátum-leíró fájlok (*.lua)Egyéb adat:FLAC képA következő fájloknál nem sikerült beállítani a metaadatokat:A fájlban nem sikerült beállítani a metaadatokat. A hiba oka: %sFájlA megadott fájl "%s" nem létezik, vagy visszavonták róla az írási jogot. Lehetséges, hogy a fájlt tartalmazó partíciót lecsatolták.Biztosan el akarod távolítani a '%s' fájl?Fájl tulajdonosaFájltípusFájl formátum:Fájl ikon (32x32 PNG)Fájl ikon (egyéb)Fájl infóFájl infó...A fájl nem írhatóFájlnév:Fájl:FájlnévFájlnév sablon:Fájlnév:Törlésre kijelölt fájlokFájlrendszerSzűrőCsak az első szónálA könyvtárstruktúrát követve határozza meg az előadókat és albumokat. A fájlok hozzáadása albumonként történik.BetűtípusokTOC újraolvasás kényszerítése minden meghajtó scannelésnélAlak megőrzése: A többi legyen kisbetűFormátumFormátum:Free Lossless Audio Codec (*.flac)Free Lossless Audio Codec (FLAC) Szabad helyFrancia: Első borítóÁltalánosÁltalános StreamMetaMűfajMűfaj:Német: Grafika:HTTP (port 80)Eszköz hard reseteléseSúgóAqualung elrejtéseKomment mező elrejtéseA Zenetár komment mezőjének elrejtéseHonlap:Vízszintes egér görgőMagyar: IDID3v1ID3v2ISBNISRCIcy-LeírásIcy-Műfaj:Icy-NévTétlenIllusztrációImplicit parancssorKomment tag importálásaReplaygain tag importálása rögzített RVA-kéntImportálás előadókéntImportálás RVA-kéntImportálás albumkéntImportálás kulcskéntImportálás címkéntImportálás track számakéntImportálás évkéntMinden esetbenCsak a mintára illeszkedő fájlok vizsgálataFüggetlenIndexKezdeti előjegyzésBemenetekHangszerekHangszerek:Internal errorInternetInternetes rádióállomás neveInternetes rádióállomás tulajdonosaFeldolgozás/remixIntroplayA 'Genre' mező értéke érvénytelenA 'Track no.' mező értéke érvénytelenAktuális állapot invertálásaKijelölés megfordításaRésztvevő emberekNagyon valószínű, hogy az év hibás. Akarod folytatni?Olasz: JACK Audio Szerver JACK port beállításMegszakadt a JACK összeköttetésA JACK szervert leállították, vagy lekapcsolta az Aqualungot, mert nem volt elég gyors. Újra kell indítani a JACK-et és az Aqualungot is.JACK port beállításJapán: Kapcsolt sztereóA főablak legyen mindig felülKulcs:LADSPA effekt szerkesztőLADSPA effekt processzálásLADSPA effekt támogatás LAME (MP3) LAVC (AC3, AAC, WavPack, WMA, stb.) LAVC hang/videó fájlokCímke kódNyelvI. RétegII. RétegIII. RétegVezető művész/előadóFüzetlapA bal és jobb gombok funkciója nem változtatható.Bal gombHosszHossz:LicencLimitekaz átlagtól vett eltérésen [dB]Max. eltérés az átlagtól [dB] :Lehallgatási környezet:Nappali szobaLejátszólista betöltéseLejátszólista betöltése új laponBeállítások betöltése a Zenetár fájlbólHelyi CDDB könyvtár:HelyHely és fájlnévLogo, ikonok: Ciklikus lejátszás támogatás Ismétlési tartomány: %d-%d%%Ismétlési tartomány: %d-%d%% [%s - %s]Lua támogatás (programozható címformátum) SzövegíróSzövegíróMIME típus: %sMOD Audio (MOD, S3M, XM, IT, stb.) MONOMP3 lejátszólista (*.m3u) MPEG Audio (*.mp3, *.mpa, *.mpega, ...)MPEG Audio (MPEG 1-2.5 I-III. Réteg) MPEG StreamMetaFőablakTalálatok:Adások maximális száma:Újrapróbálások maximális száma:Maximális helyhasználat [MB]:MédiaMemória foglalási hibaMetaadatokMetaadat szerkesztő (Fájl infó ablak)Középső gombEgyébMód:Modell:Modul infóModulok (*.xm, *.mod, *.it, *.s3m, ...)Monkey's Audio Codec Monkey's Audio Codec (*.ape)HangnemMount RainierEgérgombEgérgombokEgér görgőMozi/videó felvételMultimédia lejátszólista (*.pls)Musepack Musepack (*.mpc)Musepack ReplayGainZenetárZenetár fájlok (*.xml)Zenetár: Zenészek elismeréseNémaNULLNévRendezési kulcs:Név transzformációNév:Új lapKövetkezőKövetkező számNincs lemezAz album nem található az adatbázisban.A formátum nem támogat metaadatotNincs kimenetNincs proxy:Nem található megfelelő iRiver iFP eszköz. Lehet, hogy nincs csatlakoztatva, vagy ki van kapcsolva.No.Zajos műhelyEgyik semA lejátszód egyik kiválasztott szám formátumát sem támogatja. Akarod folytatni?Megjegyzés: a korábban meglévő tagek akkor is frissülnek, ha itt nincsenek bejelölve.OSS Audio IrodaSzerző hivatalos honlapjaAudio fájl hivatalos honlapjaAudió forrás hivatalos honlapjaRádióállomás hivatalos honlapjaOgg Speex Ogg Speex (*.spx)Ogg Vorbis Ogg Vorbis (*.ogg)Ogg Xiph megjegyzésekZenetárban egy vagy több tároló tartalma megváltozott. Szeretnéd elmenteni őket kilépés előtt?A lejátszód nem támogatja az egyik szám formátumát. Akarod folytatni?Csak ha ismeretlenOpenBSD kompatibilitás, metaadat trükkök Opcionális funkciók:SzervezetEredeti albumEredeti előadóEredeti fájlnévEredeti szövegíróEredeti kiadás idejeEgyébKimenetKimeneti meghajtók:Kimenet:KimenetekÖsszesen: Szkin beállítások felülbírálásaParanoiaParanoia hibajavításÖsszetett mű részeElérési útAbszolút vagy tildével kezdődő elérési utak szükségesek. A tilde a saját könyvtár elérési útját jelenti. A lista elemeinek átrendezésével állítható a tárolók sorrendje a Zenetárban.Abszolút vagy tildével kezdődő elérési út szükséges.A Zenetár adatbázisok elérési útjaMinták:SzünetFizetésÁtlapolt olvasások végzéseElőadóElőadó sorrendjeKép típusa:LejátszásAudio CD lejátszásaLejátszás/SzünetLejátszás indítása/szünetLejátszás indítása/megállításLejátszáskori RVAA lejátszáskori RVA jelenleg nem engedélyezett. Akarod most engedélyezni?LejátszólistaLejátszólista késleltetésOszlopok sorrendje a LejátszólistábanLejátszólista: Adj meg egy új nevet.Add meg a könyvtár nevét.Válassz egy adatbázist.Válassz egy címformátum-leíró fájlt.Válassz egy helyi elérési utat.Válassz ki legalább egy érvényes számot a lejátszólistából.Add meg a számhoz tartozó fájlt.Válaszd ki az albumhoz adandó hangfájlokat.Válassz ki egy könyvtárat az exportált fájloknak.Válassz ki egy könyvtárat a rippelt fájloknak.Válassz ki egy könyvtárat a podcasthoz letöltendő fájloknak.Válaszd ki a gyökérkönyvtárat.Add meg a tárolóhoz tartozó xml fájlt.Add meg a betöltendő képfájlt.Add meg a betöltendő lejátszólista fájlt.Add meg az elmentendő képfájlt.Add meg az elmentendő lejátszólista fájlt.Podcast URL:Podcast támogatás PodcastsPort:Pozíció: %d%%Post Fader (Hangerő és balanszszabályozó után)Pre Fader (Hangerő- és balanszszabályozó előtt)Előre definiált transzformációkElőzőElőző számMetaadatok olvasásaFeldolgozás:ProducedProfile: BraindeadProfile: InsaneProfile: RadioProfile: StandardProfile: TelephoneProfile: ThumbProfile: XtremeCímformátum-leíró fájlProgramozás, GUI tervezés: FeldolgozásFeldolgozás:Lekérdezési protokoll (közvetlen kapcsolódás esetén):Proxy host:Proxy beállításokPublikáció jogaKiadóKiadó hivatalos honlapjaKiadó/stúdió logótípusPulseAudio Vezérlőgombok elhelyezése a Lejátszólista aljánKilépésRVARVA meghatározatlan hangosságú fájlokhoz [dB] :RVA értékekCD+G olvasásaCD-DA olvasásaCD-R olvasásaCD-RW olvasásaDVD+R olvasásaDVD+RW olvasásaDVD-R olvasásaDVD-RAM olvasásaDVD-ROM olvasásaDVD-RW olvasásaISRC olvasásaMCN olvasásaMode 2 Form 1 olvasásaMode 2 Form 2 olvasásaTöbb session olvasásaOlvasásFájl olvasásaBiztosan eltávolítod a Zenetárból a következőt: "%s" ?Biztosan eltávolítod a Zenetárból a következőt: "%s" ?Biztosan eltávolítod a Zenetárból a "%s" tárolót?Hiba okaAlbumFelvétel dátumaFelvétel helyeAlbum címeAlbum címe (kisbetűvel)AlbumokFelvétel helye/stúdióHangfájlok rekurzív keresése a gyökérkönyvtárból kiindulva. A fájlok feldolgozása külön történik, ezért csak metaadatokra és fájlnév transzformációra támaszkodik.Referencia-hangerőszint [dBFS] :FrissítésA kifejezés fedi az üres karakterláncotKifejezés:Reguláris kifejezésKapcsolódóKiadás idejeEltávolításElőadó eltávolításaAlbum eltávolításaTároló eltávolításaSzám eltávolításaMindent eltávolítElőadó eltávolításaÉrvénytelen elemek eltávolításaForrás eltávolításaKiterjesztés levágásaFájlok törléseElem eltávolításaKezdő számjegyek levágásaNem létező fájlok eltávolítása a tárolóbólRégebbi adások törlése [nap]:Album eltávolításaKijelölt elemek törléseKijelölt számok törlése a lejátszólistából (jobb egérgomb: helyi menü)Tároló eltávolításaSzám eltávolításaNem létező fájlok törléseÁtnevezésLejátszólista átnevezéseForrások sorrendjének beállításaÖsszes szám ismétléseAktuális szám ismétléseCsere:ReplayGain Album GainReplayGain Album PeakReplayGain referencia hangosságReplayGain Track GainReplayGain Track PeakReplayGain tag kiválasztása (a másik tartalék lesz): Replaygain_album_gainReplaygain_track_gainLétező számok adatainak újraolvasásaMetaadatok újraolvasásaÚjraolvasFolytatásTalálatok letöltése a szerverről...Revision:Jobb gombRippelésCD rippelésCD rippelés...Számok rippeléseAktív számra ugrásGyökérkönyvtár:Működő effektekOrosz: SRC Típus: STEREOMEGÁLLÍTMintavételi frekvencia konverter támogatás Mintavételi frekvencia konverter típusaMintavételi frekvencia:Mintavételek:i frekvencia:Mintavételek:HomokozóMentésÖsszes lejátszólista mentéseÖsszes tároló mentéseMentés és bezárásLejátszólista mentése és visszatöltése kilépéskor/indításkorLejátszólista mentéseLejátszólista rendszeres mentési ideje [perc]:Tároló mentéseFájlok vizsgálataKeresésKeresés a következő helyeken:Keresés a ZenetárbanKeresés a LejátszólistábanKeresés...KiválasztásFont választása...Összes elem kijelöléseA lejátszólista összes számának kijelölése (jobb egérgomb: helyi menü)Felépítés típusának kiválasztásaKönyvtár kiválasztásaFájlok kiválasztásaElső találat kiválasztása és az ablak bezárásaJuke-box lemez kiválasztásaKijelölés megszüntetéseKiválasztott fájlok:Küldés iFP eszközreEgyéniÖsszetett mű alcímeMeghajtó sebesség beállításaBeállításokAqualung mutatásaRVA értékek megjelenítéseAktív szám megjelenítése félkövérrelLegyen bezárás gomb a fülekenBorító mutatása csak a Zenetárból hozzáadott számok eseténRejtett fájlok és könyvtárak mutatása tallózáskorSzám címének megjelenítése a főablak címsorábanHangfájl méretének mutatása az állapotsorbanElőször a tagek látszódjanak a fájl infó ablakbanSzám hosszak megjelenítéseVéletlenszerű sorrendEgyszerű nézet a LADSPA effekt szerkesztőbenEgycsatornásMéretSzkin-választóSkin támogatás, kinézet, jusztírozás: Kis időkijelzők: SzoftverSzám a Lejátszólistában: Szám info: Szám címe: Előadók rendezése a következő szerintAlbumok rendezése a következő szerintHangfájlok (*.wav, *.aiff, *.au, ...)ForrásForrás fájl:Indítás minimalizálvaÁllapotsor: Meredekség [dB/dB] :SztereóMegállításHozzáadás leállításaHozzáadás leállításaStruktúra:Alkönyvtár név maximális hossza:CD feltöltése CDDB adatbázisba...Új album feltöltéseAlbum feltöltése CDDB adatbázisba...Új forrás felvételeAlcímSikerSvéd: RendszertálcaRendszertálca támogatás Fájlok taggelése metaadatokkalTaggelés idejeMPEG audio fájlokban létrehozáskor vagy frissítéskor hozzáadandó keretek:Válassz egy könyvtárat a rippelt fájloknakCélkönyvtár:Célfájl:TesztA feltöltéshez megadott email cím érvénytelen.Az alábbi információ a meghajtótól származik, ami lehet hogy nem felel meg a készülék valódi képességeinek.A kiválasztott fájlok törlődni fognak a fájlrendszerről. Végrehajtás után nem lesz lehetőség visszaállításra. Biztosan folytatni akarod?A lejátszód nem támogatja a kiválasztott szám formátumát. Akarod folytatni?A megadott tároló már szerepel a listában.A '%s' táróló már létezik. Hozzáadása a Beállítások/Zenetár oldalon lehetséges.A fájl nem mentett metaadat változtatásokat tartalmaz.Ez az Aqualung bináris a következő opciókat támogatja:Ez a lemez nem tartalmaz CD-Text információt.Ez a gomb már be van állítva.Ez egy szabad szoftver; terjeszthető illetve módosítható a Szabad Szoftver Alapítvány által kiadott GNU Általános Közreadási Feltételek (GPL) második (vagy bármely későbbi) változatában foglaltak alapján. A programot abban a reményben adjuk közre, hogy hasznos lesz, de nem vállalunk SEMMIFÉLE GARANCIÁT; beleértve az ELADHATÓSÁGRA vagy egy BIZONYOS FELADAT ELVÉGZÉSÉRE vonatkozó származtatott garanciát is. További részletek a GNU GPL dokumentumában. A programhoz a GNU GPL egy példánya is jár; ha nem kaptad meg, írj a Szabad Szoftver Alapítvány címére: Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.Socket I/O időkorlátja:CímCímformátumCím sorrendjeA cím csupa kisbetűvel szerepel. Akarod folytatni?A cím csupa nagybetűvel szerepel. Akarod folytatni?Cím:LADSPA effekt szerkesztőZenetárLejátszólistaÖsszesenÖsszes mintavétel:Összesen: SzámTrack számaSzám kommentjeSzám hosszakSzám címeTrack számaSzámcímekSzám:SzámokFordítók:Kezdő, végző és többszörös szóközök eltávolításaTípus: URL:Ukrán: Sikertelen fájlmegnyitás%d fájl törlése sikertelen volt.%d fájl törlése sikertelen volt.Lapbezárás visszavonásaA '?' után vége van a sablonnak.Ablakok együttes minimalizálásaIsmeretlenIsmeretlen lemezIsmeretlen előadóIsmeretlen albumIsmeretlen számIsmeretlen konverziós karakter a '%%%%' után.Ismeretlen konverziós karakter a '?' után.Ismeretlen lemezIsmeretlen hibaMeghiúsult olvasások esetén tetszőleges számú újraolvasás (soha nem ugrik)IsmeretlenIsmeretlen hangerejű számokraIsmeretlenNévtelenÖsszes forrás frissítéseForrás frissítéseMetaadatok frissítéseMetaadatok frissítése...Frissítés...Fájlnév használata teljes elérési út helyett ha nincs elérhető metaadat.Rögzített RVA használata [dB]Relatív elérési utak használata a tároló fájlbanKizárólag a helyi adatbázis használataFelhasználói szövegFelhasználói URLVBR kódolásVendorVendor:Adat integritás ellenőrzéseVerzióFüggőleges egér görgőLátható név:Hangerő:Hangerő: %sFigyelmeztetés, ha az ablakkezelő nem támogatja a rendszertálcátFigyelmeztetésWavPack WavPack (*.wv)Új keret hozzáadásánál próbálja meg beállítani a tartalmát egy másik tag ekvivalens keretéből.Véletlenszerű lejátszás esetén albumon belüli számsorrend megtartásaWin32 Sound API CD-R írásaCD-RW írásaDVD+R írásaDVD+RW írásaDVD-R írásaDVD-RAM írásaDVD-RW írásaÍrásÉvÉv:Meg kell adni egy email címet a feltöltéshez.A következő változtatások az Aqualung újraindítása után jutnak érvényre:_MegszakításFájlok _hozzáadása..._Tallózás..._Beállítás_Letöltés_Feltöltéselőadóelőadólegjobbbites dupla pontosságú lebegőpontosbites lebegőpontosbites előjeles egészbites előjel nélküli egészszámolás alatt...napnapmeghajtómeghajtókódolásúgyorsforrásforrásmező:iFP eszközkezelő (letöltés mód)iFP eszközkezelő (feltöltés mód)iRiver iFP meghajtó támogatás adásadásúj adásúj adásralbumalbumgyökér / előadó / előadó / előadó / album / számgyökér / előadó / előadó / album / számgyökér / előadó / album / számgyökér / album / számrwmásodpercsndfile (WAV) sndfile (WAV, AIFF, stb.) sndio Audio tag:számszámnem elérhetőablak szélességéhez igazítaqualung-0.9beta11/src/po/it.mo0000644000175000001440000016073711331334313013301 00000000000000:O3DD4EFJEF[JG HHHH HHHII2IDI XIfIOlIIII I III J J 1JP>P Q Q %Q(2Q[QlQ(tQQQ Q QQQ$QRR!jR&RRRRRSS S S)S8SMS \SgSoS uS S SSS'SSSS T(T*T>TGTWTpTuT T TTT T TT UU$UD=UU UUUU UUU UU V VV #V -V8V#SVwVVVVV VVVVV W)W HRj T$ 3@Wu Ò Β ے 2I] | &)$86] L1D!^33#7 D^s(5˖$&,;BH [hN×I \:fMV W` ś ޛ'%&.Uh q |,/b+M+yŝݝ -<N]mv }Ğ3˞  )' Q\^u~ ʟ؟$+ =JY kwL & 6 @KRdl &ʡ5'=DLU ^h ݢ$7Lb!x&ܣI'/W ]g(+ˤ  '< Y"z¥ǥإ) . : GTKn#ަZ o}/ħ.C I Tb r NA٨0>L"jǩ2F UckǪت %>Sg"o4ǫϫ߫2)L(v"Ҭ $4b; #A\u ׮  ,<:6w<  !8 LVo   !Ȱ E#\"! ֱ "#2V\!n1 ² ̲ز۲ #<Qb} ɳ7ֳ " + 5@OXv19$@6 wƵm#˶ $ 0FW^f oy ķط  "+?k  #'$'L\t #߹&8N ky   غ " ,7 JNW6ݻkjod '=!e  ýaսM7ľԾ<D K)U Q$)2 8 BL [e x># !&7^+|60@+Q6},--,=/j+ .03d ' F P5[ 0  $ / ; F R ^ k w . .O.~ $!9[z2  0> N[ s(&`i}"-"Gj},   #.05fu ~5$<Nj pz \;N'] $%6&\?O/Cbt .#6%Ou~ *6*4Cx >+*Vl~*t$X7.>)m4_wL~K*2Jau|    *"E!h5B $6Jdx1   )7"Twl-, HU\d 9  " . ; H Vc s5K !, @ K V`hpx ,*5`|  <2 (<e`+0=j G1gR  E u2pGrgH)cq*ot9/.AqB;.0$6C7_#has;R?&/`uF} 0 W ,-' b X 1!u>Ks~RS0jB@VtcT65^d5f y>h8 ,lD'CN+X #9G]v 2|SlM[\'^QD5$byz3J^'d"r"!HJ|&? j/UYO-@O.}~9L VU[\)->&sL{:\i# n/qZ: 5%xThQS87-kF4<p$(,f+z_lcUZ4wT:i4zk)= v7NEMVICwe8{MFIN7E]nrp & #|!m%O.X8ov1WB:i"PP*3_$*P!QtL}gnA(=x~Ze"k[91?Kw3+Y@6aHaofJ34b{ ](I(Y,Wx*2<DmK%%<d`e my )2;A6 Maximum number of retries: Destination directory is not read-write accessible! The Music Store you selected has a matching Artist and Album, already containing some tracks. If you press OK, these tracks will be removed. The files themselves will be left intact, but they will be removed from the destination Music Store. Press Cancel to get back to change the Artist/Album or the destination Music Store. The template string you enter here will be used to construct a single title line from an Artist, a Record and a Track name. These are denoted by %%%%a, %%%%r and %%%%t, respectively. The template string you enter here will be used to construct the filename of the exported files. The Artist, Record and Track names are denoted by %%%%a, %%%%r and %%%%t. The track number and format-dependent file extension are denoted by %%%%n and %%%%x, respectively. The flag %%%%i gives an identifier which is unique within an export session. (%.1f MB) (%d/%d) (capacity = %.1f MB) Free space (%.1f MB) Selected: out L out R% of standard deviation% of standard deviation :%.1f MB / %.1f MB%d / %d directories%d / %d files%d dB%d of %d songs have format unsupported by your player. Do you want to proceed?%d%% L%d%% R%ld Hz(Untitled)(audio only)(choose a category)(error loading image)(no comment)(no description)(no image)(none)*File info*Music Store100 pixels200 pixels300 pixels50 pixelsDevice statusLocal directoryRemote directorySongs infoTransfer progressALSA Audio APEAbortAborted...AboutAbstractAccessAction:Active song in playlist: AddAdd ArtistAdd RecordAdd TrackAdd URLAdd all items to playlistAdd all items to playlist (Album mode)Add directoryAdd filesAdd files to playlist (Press right mouse button for menu)Add item...Add new artist to this store...Add new artist...Add new items to playlistAdd new items to playlist (Album mode)Add new record to this artist...Add new record...Add new track to this record...Add new track...Add to CommentsAdd to Music StoreAdd to playlistAdd to playlist (Album mode)Add year to the comments of new recordsAdding files to PlaylistAlbumAlbum imageAlbum:AllAll Audio FilesAll FilesAll Playlist FilesAll tracksAll wordsAlways show the tab barAn error occurred while attempting to connect to the CDDB server.An error occurred while submitting the record to the CDDB server.AppearanceApply averaged RVA to tracks of the same recordAqualung is compiled with system tray support, but the status icon could not be embedded in the notification area. Your desktop may not have support for a system tray, or it has not been configured correctly.Aqualung is compiled without LADSPA plugin support. See the About box and the documentation for details.Aqualung is compiled without Sample Rate Converter support. See the About box and the documentation for details.Aqualung playlist (*.xml)ArtistArtist appears to be in all lowercase. Do you want to proceed?Artist appears to be in all uppercase. Do you want to proceed?Artist nameArtist name (lowercase)Artist namesArtist/Album already existing, not emptyArtist/performerArtist:Ask for confirmation when removing itemsAttached PictureAudio CDAudio dataAudiophileAuthors:Auto-check interval [hour]:Auto-create tracks from these files:Automatic update has been disabled for all feeds in the Podcasts store popup menu.Automatically add CDs to PlaylistAutomatically remove CDs from PlaylistAutomatically update feedsAvailable connectionsAvailable pluginsAvailable skinsAverageBPMBack coverBalance: %sBand/OrchestraBand/artist logotypeBand/orchestraBandwidth:BatteryBeginBibliographyBig timer: Binary ObjectBitrate [kbps]:BrowseBuild / Update store from filesystem...Build version: Build/Update storeBuilding store from filesystemBurn ProofCC2 Error CorrectionCD AudioCD drive speed:CDDA (Audio CD) support CDDBCDDB (not available)CDDB lookupCDDB queryCDDB query for this CD...CDDB query for this record...CDDB server:CDDB support CDDBP (port 888)Calculate RVACalculate volumeCalculating volume levelCannot write to selected directory. Please select another directory.CapitalizationCapitalize: Case sensitiveCatalog NumberCategoryCategory:ChangeChannel count:Channels:Clear connectionsClear listCloseClose other tabsClose tabClose trayClose window when completeClose window when transfer completeCollapse all itemsColorsColumnCommentCommentsComments:Commercial InformationComposerCompressed modules (*.bz2)Compressed modules (*.gz)Compressed modules (*.gz, *.bz2)Compression level:Compression: Extra HighCompression: FastCompression: HighCompression: InsaneCompression: NormalConductorConnect via HTTP proxyConnecting to CDDB server...Connection timeout [sec]:ContactConversion error in field %s: '%s' does not conform to format '%s'!Convert underscore to spaceCopyCopyrightCopyright/Legal InformationCore design, engineering & programming: Correct existing recordCould not load image from: %sCover artCreate a new directoryCreate directoryCreate empty storeCreate empty store...Create subdirectories for albumsCreate subdirectories for artistsCurrent file: Cut selectedDSPDateDebut AlbumDecoding support:Default cover width:Delete downloaded items from the filesystemDescriptionDescription:DestinationDetect media changeDevice is busy. (Aqualung was unable to claim its interface.)Device is not responding. Try jiggling the handle.Device path:Direct connection to the InternetDirectory '%s' will be removed with its entire contents. Do you want to proceed?Directory nameDirectory name (lowercase)Directory structureDisable all pluginsDisable control buttons reliefDisable manual ejectDisable skin supportDiscDisc infoDisc info...Discard changesDo not closeDo not exitDo not reencode files already being in the target formatDo you want to save store "%s" before removing from Music Store?Do you want to save the store before removing?Don't show cover thumbnail in the main windowDoneDownload directory:Downloading %d/%d (%d%%) ...Drag and drop entries in the list below to set the column order in the Playlist.Drive infoDrive info...Dual channelDuration:During recordingEAN/UPCEdit ArtistEdit RecordEdit StoreEdit TrackEdit artist...Edit feedEdit feed settingsEdit item...Edit record...Edit store...Edit track...EjectEmail address for submission:Embed playlist into main windowEmphasis:Emphasis: noneEmphasis: reservedEnable all pluginsEnable playback RVAEnable rules hintEnable statusbarEnable statusbar in Music StoreEnable statusbar in playlistEnable toolbarEnable toolbar in Music StoreEnable tooltipsEnabledEncoded byEncoding TimeEncoding support:Enqueue playlistErrorError converting field %s to Year: '%s' is not an integer number!Error in format stringError in title format stringExact matches onlyExpand Stores on startupExpected '}' after '{', but end of string found.Export all items...Export artist...Export filesExport item...Export new items...Export record...Export store...Export track...Exporting filesExtended data:FLAC PicturesFailed to set metadata for the following files:Failed to write metadata to file. Reason: %sFileFile '%s' will be removed. Do you want to proceed?File OwnerFile TypeFile format:File icon (32x32 PNG)File icon (other)File infoFile info...File is not writableFile name: File:FilenameFilename template:Filename:Files selected for removalFilesystemFilterFirst word onlyFontsForce TOC re-read on every drive scanForce other letters to lowercaseFormatFormat:Free Lossless Audio Codec (*.flac)Free Lossless Audio Codec (FLAC) Free spaceFront coverGeneralGenreGenre:German: Graphics:HTTP (port 80)Hard reset deviceHelpHide AqualungHide comment paneHide the Music Store comment paneHomepage:Hungarian: IDID3v1ID3v2ISBNISRCIdleIllustrationImplicit command lineImport Comment tagImport as ArtistImport as RVAImport as RecordImport as TitleImport as Track No.Import as YearIn any caseInclude only files matching wildcardIndependentIndexInputsInstrumentsInstruments:Internal errorInternetInternet Radio Station NameInterpreted/RemixedInvalid 'Genre' field valueInvalid 'Track no.' field valueInvert current stateInvert selectionInvolved PeopleIt is very likely that the year is wrong. Do you want to proceed?Italian: JACK Audio Server JACK Port SetupJACK connection lostJACK has either been shutdown or it disconnected Aqualung because it was not fast enough. All you can do now is restart both JACK and Aqualung.JACK port setupKeep main window always on topKey: LADSPA patch builderLADSPA plugin processingLADSPA plugin support LAME (MP3) LAVC (AC3, AAC, WavPack, WMA, etc.) LAVC audio/video filesLabel CodeLanguageLayer ILayer IILayer IIILead artist/performerLeaflet pageLengthLength:LicenseLimitsLinear threshold [dB]Linear threshold [dB] :Listening environment:Living roomLoad playlistLoad playlist in new tabLoad settings from Music Store fileLocal CDDB directory:LocationLocation and filenameLogo, icons: MIME type: %sMOD Audio (MOD, S3M, XM, IT, etc.) MONOMP3 Playlist (*.m3u)MPEG Audio (*.mp3, *.mpa, *.mpega, ...)MPEG Audio (MPEG 1-2.5 Layer I-III) MPEG StreamMetaMaximum number of items:Maximum number of retries:Maximum space to use [MB]:MediaMemory allocation errorMetadataMiscellaneousMode:Model:Module infoModules (*.xm, *.mod, *.it, *.s3m, ...)Monkey's Audio Codec Monkey's Audio Codec (*.ape)Mount RainierMultimedia Playlist (*.pls)Musepack Musepack (*.mpc)Music StoreMusic Store Files (*.xml)Music Store: MuteNULLNameName to sort by:Name transformationName:New tabNextNext songNo discNo matching record found.No metadata support for this formatNo outputNo proxy for:No suitable iRiver iFP device found. Perhaps it is unplugged or turned off.No.Noisy workshopNoneNone of the selected songs has format supported by your player. Do you want to proceed?OSS Audio OfficeOfficial Artist WebsiteOfficial Audio File WebsiteOfficial Audio Source WebsiteOfficial Radio Station WebsiteOgg Speex Ogg Speex (*.spx)Ogg Vorbis Ogg Vorbis (*.ogg)Ogg Xiph CommentsOne or more stores in Music Store have been modified. Do you want to save them before exiting?One song has format unsupported by your player. Do you want to proceed?Only if unmeasuredOptional features:OrganizationOriginal AlbumOriginal ArtistOriginal FilenameOriginal LyricistOtherOutputOutput driver support:Output:OutputsOverall: Override skin settingsParanoiaParanoia error correctionPathPaths must either be absolute or starting with a tilde.Paths to Music Store databasesPatterns:PausePaymentPerformerPicture type:PlayPlay CD AudioPlayback RVAPlayback RVA is currently disabled. Do you want to enable it now?PlaylistPlaylist column orderPlaylist: Please enter a new name.Please enter directory name.Please select a Music Store database.Please select a local path.Please select at least one valid song from playlist.Please select the audio file for this track.Please select the audio files for this record.Please select the directory for exported files.Please select the directory for ripped files.Please select the download directory for this podcast.Please select the root directory.Please select the xml file for this store.Please specify the file to load the image from.Please specify the file to load the playlist from.Please specify the file to save the image to.Please specify the file to save the playlist to.Podcast URL:Podcast support PodcastsPort:Position: %d%%Post Fader (after Volume & Balance)Pre Fader (before Volume & Balance)Predefined transformationsPreviousPrevious songProcessing metadataProcessing:ProducedProfile: InsaneProfile: RadioProfile: StandardProfile: TelephoneProfile: XtremeProgramming, GUI engineering: ProgressProgress:Protocol for querying (direct connection only):Proxy host:Proxy settingsPublication RightPublisherPut control buttons at the bottom of playlistQuitRVARVA valuesRead CD+GRead CD-DARead CD-RRead CD-RWRead DVD+RRead DVD+RWRead DVD-RRead DVD-RAMRead DVD-ROMRead DVD-RWRead ISRCRead MCNRead Mode 2 Form 1Read Mode 2 Form 2Read multiple sessionsReadingReading fileReally remove "%s" from the Music Store?Really remove '%s' from the Music Store?Really remove store "%s" from the Music Store?RecordRecord DateRecord LocationRecord nameRecord name (lowercase)Record titlesRecording location/studioReference volume [dBFS] :RefreshRegexp matches empty stringRegexp:Regular expressionRemoveRemove ArtistRemove RecordRemove StoreRemove TrackRemove allRemove artistRemove feedRemove file extensionRemove filesRemove item...Remove non-existing files from storeRemove older items [day]:Remove recordRemove selectedRemove selected songs from playlist (Press right mouse button for menu)Remove storeRemove trackRemoving non-existing filesRenameRename playlistReorder feedsRepeat all songsRepeat current songReread data for existing tracksReread file metadataRescanResumeRetrieving matches from server...Revision:RipRip CDRip CD...Ripping CD tracksRoot path:Running pluginsRussian: SRC Type: STEREOSample Rate Converter support Samplerate:SamplesSamples:SaveSave all playlistsSave all storesSave and closeSave and restore the playlist on exit/startupSave playlistSave playlist periodically [min]:Save storeScanning filesSearchSearch in:Search the Music StoreSearch the PlaylistSearch...SelectSelect a font...Select allSelect all songs in playlist (Press right mouse button for menu)Select directorySelect filesSelect first and close windowSelect noneSelected files:Send to iFP deviceSeparateSet SubtitleSet drive speedSettingsShow AqualungShow RVA valuesShow active track name in boldShow close button in tabShow hidden files and directories in file choosersShow song name in the main window's titleShow soundfile size in statusbarShow track lengthsShuffle songsSingle channelSizeSkin chooserSkin support, look & feel, GUI hacks: Small timers: SoftwareSong in playlist: Song info: Song title: Sort artists bySort records bySound Files (*.wav, *.aiff, *.au, ...)SourceSource file:Statusbar: Steepness [dB/dB] :StereoStopStructure:Subdirectory name length limit:Submit CD to CDDB database...Submit new recordSubmit record to CDDB database...Subscribe to new feedSubtitleSuccessSystray support Tag files with metadataTags to add when creating or updating MPEG audio files:Target directory for ripped filesTarget directory:Target file:TestThe email address provided for submission is invalid.The information below is reported by the drive, and may not reflect the actual capabilities of the device.The selected files will be deleted from the filesystem. No recovery will be possible after this operation. Do you want to proceed?The selected song has format unsupported by your player. Do you want to proceed?The specified store has already been added to the list.There are unsaved changes to the file metadata.This Aqualung binary is compiled with:This CD does not contain CD-Text information.This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.Timeout for socket I/O:TitleTitle appears to be in all lowercase. Do you want to proceed?Title appears to be in all uppercase. Do you want to proceed?Title formatTitle:Toggle LADSPA patch builderToggle music storeToggle playlistTotalTotal samples:Total: TrackTrack No.Track commentTrack lengthsTrack nameTrack numberTrack titlesTrack:TracksTranslators:Type:URL:Ukrainian: Unable to open fileUnable to remove %d file.Unable to remove %d files.Undo close tabUnexpected end of string after '?'.United windows minimizationUnknownUnknown AlbumUnknown ArtistUnknown RecordUnknown TrackUnknown discUnknown errorUnlimited retry on failed reads (never skip)UnmeasuredUnmeasured tracks onlyUnrecognizedUntitledUpdate all feedsUpdate feedUpdate file metadataUpdate file metadata...Updating...Use basename only instead of full path if no metadata is available.Use manual RVA value [dB]Use the local database onlyVBR encodingVendorVendor:Verify data integrityVersionVisible name:Volume level:Volume: %sWarn me if the Window Manager does not support system trayWarningWavPack WavPack (*.wv)Win32 Sound API Write CD-RWrite CD-RWWrite DVD+RWrite DVD+RWWrite DVD-RWrite DVD-RAMWrite DVD-RWWritingYearYear:You have to provide an email address for CDDB submission.You will need to restart Aqualung for the following changes to take effect:_Abort_Add files..._Browse..._Configure_Download_Uploadartistartistsbestbit doublebit floatbit signedbit unsignedcounting...daydaysdrivedrivesencodingfastfeedfeedsfield:iFP device manager (download mode)iFP device manager (upload mode)iRiver iFP driver support itemitemslabel_songsnew itemnew itemsrrecordrecordsroot / artist / artist / artist / record / trackroot / artist / artist / record / trackroot / artist / record / trackroot / record / trackrwsecondssndfile (WAV) sndfile (WAV, AIFF, etc.) tag:tracktracksunreachableProject-Id-Version: it Report-Msgid-Bugs-To: POT-Creation-Date: 2008-04-18 23:07+0200 PO-Revision-Date: 2008-04-19 21:55+0200 Last-Translator: Michele Petrecca Language-Team: Italiano MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Generator: KBabel 1.11.4 Massimo numero di tentativi: La cartella di destinazione non è accessibile in lettura-scrittura! Il Music Store che hai selezionato ha una coincidenza con con Artista e Album contenente già alcune tracce. Se premi OK, queste tracce verranno rimosse. Gli stessi file rimarranno integri, ma verranno rimossi dal Music Store di destinazione. Premi Cancella per ritornare indietro a cambiare Artista/Album o il Music Store di destinazione. Il modello che inserirai qui verrà utilizzato per costruire un titolo dal nome di un Artista, una Registrazione e una Traccia. Questo verrà indicato con %%%%a, %%%%r and %%%%t, rispettivamente. La stringa che inserisci qui, verrà utilizzata per costruire il nome del file del file esportato. L'Artista, la Registrazione e il nome della Traccia verranno indicate con %%%%a, %%%%r e %%%%t. Il numero della traccia e il formato del file (estensione) verranno riportate come segue %%%%n e %%%%x, rispettivamente. La variabile %%%%i fornisce un identificatore unico all'interno di ogni sessione esportata. (%.1f MB) (%d/%d) (capacità = %.1f MB) Spazio libero (%.1f MB) Selezionato: uscita S uscita DDeviazione standard [%][%] deviazione standard :%.1f MB / %.1f MB%d / %d cartelle%d / %d file%d dB%d di %d canzoni presentano un formato non supportato dal lettore. Vuoi continuare?%d%% L%d%% R%ld Hz(Senza titolo)(solo audio)(scegli una categoria)(errore caricamento immagine)(nessun commento)(nessuna descrizione)(nessuna immagine)(nessun risultato)*Info file*Music Store100 pixel200 pixel300 pixel50 pixelStato dispositivoCartella localeCartella remotaInfo canzoniProgresso trasferimentoAudio ALSA APEAnnullaAnnullato...AltroAbstractAccessoAzione:Traccia in esecuzione nella playlist: AggiungiAggiungi artistaAggiungi registrazioneAggiungi tracciaAggiungi l'URLAggiungi tutte le voci alla playlistAggiungi tutte le voci alla playlist (modalità Album)Aggiungi cartellaAggiungi fileAggiungi i file alla playlist (Premi il tasto destro del mouse per il menù)Aggiungi voce...Aggiungi un nuovo artista a questo Music Store...Aggiungi nuovo artista...Aggiungi nuove voci alla playlistAggiungi nuove voci alla playlist (modalità Album)Aggiungi una nuova registrazione a quest'artista...Aggiungi una nuova registrazione...Aggiungi una nuova traccia all'attuale registrazione...Aggiungi nuova traccia...Aggiungi ai commentiAggiungi al Music StoreAggiungi alla playlistAggiungi alla playlist (modalità album)Aggiungi l'anno ai commenti della nuova registrazioneAggiunta file in corso alla PlaylistAlbumImmagine albumAlbum:TuttoTutti i file audioTutti i fileTutti i file della playlistTutte le tracceTutte le paroleMostra sempre la barra dei tabSi è verificato un errore durante il tentativo di connessione al server CDDB.E' avvenuto in errore durante l'interrogazione della voce al server CDDB.ApparenzaApplica RVA mediato alle tracce della stessa registrazioneAqualung è stato compilato con il supporto alla system tray, ma lo stato dell'icona potrebbe non essere inserita nell'area di notificazione. L'ambiente desktop da te in uso potrebbe non avere il supporto alla system tray oppure non essere configurato in maniera appropriata.Aqualung è stato compilato senza il supporto per per i plugin LADSPA. Andare nella sezione "Altro" e leggere la documentazione per ulteriori dettagli.Aqualung è stato compilato senza il supporto alla "Conversione della frequenza di campionamento". Si rimanda alla documentazione per ulteriori dettagli.Playlist Aqualung (*.xml)ArtistaIl nome dell'artista sembra essere scritto tutto a lettere minuscole. Vuoi continuare?Il nome dell'artista sembra essere scritto tutto in lettere maiuscole. Vuoi continuare?Nome artistaNome artista (minuscolo)Nome artistaArtista/Album già esistente, non vuotoArtista/EsecutoreArtista:Chiedi conferma quando rimuovi le vociImmagine collegataCD AudioDati audioAudiofiloAutoriIntervallo per la verifica automatica (ore):Crea in automatico le tracce dai seguenti file:L'aggiornamento automatico è stato disabilitatoper tutti i feed nella pop-up dello store Podcast.Aggiungi automaticamente i CD alla playlistRimuovi automaticamente i CD dalla playlistAggiorna automaticamente i feedConnessioni disponibiliPlugin disponibiliSkin disponibiliMediaBPMCopertina retroBilanciamento: %sBand/OrchestraLogo Band/ArtistaBand/OrchestraBanda passante:BatteriaInizioBibliografiaContatore - Cifre grandi:Oggetto bianrioBitrate [kbps]:NavigaCostruisci / Aggiorna Music Store dal filesystem...Versione:Costruisci/Aggiorna magazzinoMusic store in costruzione dal filesystemBurn ProofCCorrezione d'errore C2CD AudioVelocità lettore CD:Supporto CDDA (CD Audio) CDDBCDDB (non disponibile)Cerca in CDDBInterrogazione CDDBInterrogazione CDDB per questo CD...Richiesta CDDB per il documento indicato...Server CDDB:Supporto CDDB CDDBP (porta 888)Calcola RVACalcola volumeCalcolo volume livello in corsoNon è possibile scrivere nella cartella indicata; indica un altro percorso.CapitalizzazioneCapitalizza: Distingui maiuscoleNumero catalogoCategoriaCategoria:CambioModalita' canali:Canali:Cancella connessioniCancella la listaChiudiChiudi gli altri tabChiudi tabChiudi carrelloChiudi la finestra quando ha terminatoChiudi la finestra quando il trasferimento ha termineContrae tutte le vociColoriColonnaCommentoCommentiCommenti:Informazione commercialeCompositoreModuli compressi (*.bz2)Moduli compressi (*.gz)Moduli compressi (*.gz, *.bz2)Livello di compressione:Compressione: Molto AltaCompressione: VeloceCompressione: AltaCompressione: InsanaCompressione: NormaleDirettore d'orchestraConnessione attraverso proxy HTTPConnessione in corso al server CDDB...Timeout connessione [sec]:ContattoErrore di conversione nel campo %s: '%s' non è conforme al formato '%s'!Converti l'underscore (_) in uno spazioCopiaCopyrightCopyright - Informazioni LegaliCore design, engineering & programming: Correggi le voci esistentiNon è possibile caricare l'immagine da: %sCopertinaCrea una nuova cartellaCrea cartellaCrea uno Store vuotoCrea un Music Store vuoto...Crea sottocartelle per gli albumCrea sottocartelle per gli artistiFile corrente: Taglia selezioneDSPDataAlbum di debuttoSupporto decoding:Ampiezza immagine album:Cancella dal filesystem le voci scaricateDescrizioneDescrizione:DestinazioneRileva cambio dispositivoDispositivo occupato. (Aqualung non è in grado di interfacciarsi con esso)Il dispositivo non sta rispondendo.Percorso dispositivo:Connessione diretta ad InternetLa cartella '%s' verrà rimossa insieme al suo contenuto. Sei sicuro di voler continuare?Nome cartellaNome cartella (minuscolo)Struttura cartelleDisabilita tutti i pluginDisabilita il rilievo per i pulsanti non attiviDisabilita l'espulsione manualeDisabilita il supporto alle diverse interfacceDiscoInfo DiscoInfo disco...Annulla i cambiNon chiudereNon uscireNon codificare di nuovo i file che gia' si trovano nel formato di destinazioneVuoi salvare lo store "%s" prima della rimozione dal Musci Store?Vuoi salvare il Music Store prima di rimuoverlo?Non mostrare la miniatura dell'album nella finestra principaleFattoCartella download:Download in corso %d/%d (%d%%) ...Ordina le voci della lista nel riquadro sottostante per impostare l'ordine di apparizione nella playlist.Informazioni driverInfo driver...Canale doppioDurata:Durata della registrazioneEAN/UPCModifica l'artistaModifica registrazioneModifica StoreEdita la tracciaEdita l'artista...Modifica feedModifica impostazioni feedEdita le voci...Modifica il documento...Edita Music Store...Edita la traccia...EspelliIndirizzo e-mail per le richieste:Integra la playlist all'interno dell'area principaleEnfasi:Enfasi: nessunaEnfasi: riservataAbilita tutti i pluginAbilita playback RVAAbilita suggerimentiAbilita la barra di statoAbilita la barra di stato nel Music StoreAbilita la barra di stato nella playlistAbilita toolbarAbilita la toolbar nel Music StoreAbilita suggerimentiAbilitatoCodificato daTempo di codificaSupporto Encoding:Accoda playlistErroreErrore di conversione del campo %s in Anni: '%s' non è un numero intero atto ad indicare un anno!Errore nel formato della stringaErrore nel titolo (formato stringa)Solo le parole coincidentiEspandi gli Store all'avvioEra atteso il carattere '}' dopo '{', ma la stringa è terminata.Esporta tutte le voci...Esporta artista...Esporta fileEsporta voce...Esporta nuove voci...Esporta la registrazione...Esporta Music Store...Esporta la traccia...Esportazione file in corsoDati estesi:Immagine FLACNon è stato possibile impostare i metadati per questi file:Non è stato possibile scrivere i metadati. Motivo: %sFileIl file '%s' verrà rimosso. Sei sicuro di vole continuare?Proprietario del fileTipo di fileFormato file:Icona file (32x32 PNG)Icona file (altro)Info fileInformazioni sul file...Il file non è scrivibileNome file: File:Nome fileNome file del template:Nome file:File selezionati per la rimozioneFilesystemFiltroSolo la prima parolaFontForza di nuovo la lettura della TOC ad ogni scansione del dispositivoForze le altre lettere in minuscoloFormatoFormato:Free Lossless Audio Codec (*.flac)Free Lossless Audio Codec (FLAC) Spazio liberoCopertina frontaleGeneraleGenereGenere:Tedesco: Grafici:HTTP (porta 80)Azzeramento forzato del dispositivoAiutoNascondi AqualungNascondi il pannello dei commentiNascondi il pannello dei commenti del Music StoreHomepage:Ungherese: IDID3v1ID3v2ISBNISRCIdleIllustrazioneComandi impliciti ad una shellImporta commenti dai tagImporta come artistaImporta come RVAImporta come registrazioneImporta come titoloImporta come traccia N.roImporta in funzione dell'annoIn ogni casoInclude solo i file che combaciano con le parole chiaviIndipendenteIndiceIngressiStrumentiStrumenti:Errore internoInternetNome Stazione Radio Internet Interpretato/RemixatoIl campo 'Genere' presenta un valore non correttoIl campo 'Numero traccia' presenta un valore non correttoInverti lo stato correnteInverti selezionePersone coinvoltePotrebbe darsi che l'anno non risulta corretto. Vuoi continuare?Italiano: Server audio JACK Impostazioni porte JACKConnessione a JACK persaJACK è stato chiuso oppure ha disconnesso Aqualung perché il player non era sufficientemente veloce. Per continuare a sentire le playlist devi (ri)avviare entrambe.Impostazioni JACKMantieni la finestra sopra le altreParola chiave: Finestra effetti LADSPAProcessamento plugin LADSPASupporto plugin LADSPA LAME (MP3) LAVC (AC3, AAC, WavPack, WMA, etc.) File LAVC audio/videoCodice etichettaLinguaLayer ILayer IILayer IIIArtista/Esecutore principaleManifestoLunghezzaLunghezza:LicenzaLimitiSoglia lineare [dB]Soglia lineare [dB] :Ambiente d'ascolto:SoggiornoCarica playlistCarica la playlist in un nuovo tabCarica le impostazioni dal Music Store FileCartella locale CDDB:LocazioneLocazione e nome del fileIcone, logo: Tipo MIME: %sMOD Audio (MOD, S3M, XM, IT, etc.) MONOPlaylist MP3 (*.m3u)MPEG Audio (*.mp3, *.mpa, *.mpega, ...)MPEG Audio (MPEG 1-2.5 Layer I-III) MPEG StreamMetaMassimo numero di voci:Numero massimo di tentativi:Massimo spazio da usare [MB]:DispositivoErrore di allocazione della memoriaMetadatiVarieModo:Modello:Informazioni moduloModuli (*.xm, *.mod, *.it, *.s3m, ...)Monkey's Audio Codec Monkey's Audio Codec (*.ape)Mount RainierPlaylist Multimediale (*.pls)Musepack Musepack (*.mpc)Music StoreMusic Store Files (*.xml)Music Store: MuteNULLNomeNomi ordinati per:Trasformazione nomeNome:Nuovo tabSuccessivoCanzone successivaNessun discoNessuna registrazione coincidente con le parole della ricerca è stata trovataNessun metadato supportato per questo formato di file Nessuna uscitaNessun proxy per:Nessun dispositivo iRiver iFP è stato trovato. Probabilmente e' spento oppure non rilevato (se collegato).N.roLocale pubblicoNessunoNessuna delle canzoni selezionate presentano un formatonon supportato dal lettore. Vuoi continuare?Audio OSS UfficioSito WEB ufficiale dell'artistaSito WEB file audio ufficialeSito WEB ufficiale della sorgente audioSito WEB ufficiale stazione radioOgg Speex Ogg Speex (*.spx)Ogg Vorbis Ogg Vorbis (*.ogg)Commenti Ogg XiphUna o più modifiche sono state fatte nel Music Store. Vuoi salvare le modifiche prima di uscire?Una canzone presenta un formato non supportato dal lettore. Vuoi continuare?Solo se non misuratoCaratteristiche opzionali:OrganizzazioneAlbum originaleArtista originaleNome del file originaleParoliere originaleAltroUscitaDriver di uscita supportato:Uscita:UsciteGlobale: Modifica le impostazioni delle interfacceParanoiaCorrezione d'errore con ParanoiaPercorsoL'indicazione del percorso deve essere assoluto oppure indicato tramite la tilde.Percorso al database del Music StorePattern:PausaPagamentoEsecutoreTipo immagine:RiproduciRiproduci CD AudioPlayback RVAPlayback RVA e' attualmente disabilitato. Vuoi abilitarlo ora?PlaylistOrdine delle colonne nella playlistPlaylist: Inserisci un nuovo nome.Inserisci il nome della cartella.Seleziona un database del Music Store.Seleziona un percorso locale.Seleziona almeno una canzone dalla playlistPer favore seleziona il file audio per questa traccia.Seleziona i file audio per questa registrazione.Per favore seleziona la cartella da destinare ai file esportati.Seleziona la cartella per i file convertitiSeleziona la cartella del downlaod per questo podcast.Per favore seleziona la cartella principale.Seleziona il file xml per questo music store.Specifica l'immagine da caricare con il file.Specifica il file da salvare dalla playlist.Specifica l'immagine da salvare insieme al fileSpecifica il file da salvare alla playlist.URL Podcast:Supporto Podcast PodcastPorta:Posizione: %d%%Post Fader (dopo il Volume e il Bilanciamento)Pre Fader (prima del Volume e del Bilanciamento)Trasformazioni predefinitePrecedenteCanzone precedenteAnalisi dei metadati in corsoProcessamento:ProdottoProfilo: InsanoProfilo: RadioProfilo: StandardProfilo: TelefonoProfilo: EstremoProgramming, GUI engineering: ProgressoProgresso:Protocollo interrogazione (solo connessione diretta):Host proxy:Impostazioni ProxyDiritti di pubblicazioneEditore - DivulgatoreSposta i pulsanti di controllo sotto la playlistEsciRVAValori RVALeggi CD+GLeggi CD-DALeggi CD-RLeggi CD-RWLeggi DVD+RLeggi DVD+RWLeggi DVD-RLeggi DVD-RAMLeggi DVD-ROMLeggi DVD-RWLeggi ISRCLeggi MCNLettura Mode2/Form1Lettura Mode2/Form2Leggi sessioni multipleLettura in corsoLettura in corso dei fileVuoi veramente rimuovere "%s" dal Music Store?Vuoi veramente rimuovere '%s' dal Music Store?Vuoi veramente rimuovere "%s" dal Music Store?RegistrazioneData della registrazioneLocalità della registrazioneNome registrazioneNome registrazione (minuscolo)Titoli registrazioneLocalità/Studio di registrazioneVolume di riferimento [dBFS] :AggiornaEspressione regolare coincide con la stringa vuotaEspr. regolare:Espressione regolareRimuoviRimuovi artistaRimuovi registrazioneRimuovi il Music StoreRimuovi tracciaRimuovi tuttoRimuovi artistaRimuovi feedRimuovi estensione fileRimuovi fileRimuovi voce...Rimuove i file non esistenti dallo StoreRimuovi le voci più vecchie [giorni]:Rimuovi registrazioneRimuovi selezioneRimuovi le tracce selezionate nella playlist (Clicca con il tasto destro del mouse per il menù)Rimuovi Music StoreRimuovi la tracciaRimozione di un file non esistenteRinominaRinomina plylistOrdina nuovamente i feedRipeti tutte le canzoniRipeti la canzone correnteLeggi di nuovo i dati per le tracce esistentiLeggi di nuovo i metadati del fileScansiona di nuovoRecuperaRecupero informazioni in corso dal server...Revisione:RipRip CDRip CD...Rippaggio tracce CD in corsoPercorso principale:Avvio plugin in corsoRusso: Tipo SRC: STEREOSupporto Conversione Frequenza di Campionamento Campionamento:CampioniCampioni:SalvaSalva tutte le playlistSalva tutti i Music StoreSalva e chiudiSalva la playlist all'uscita e ripristinala all'avvioSalva la playlistSalva playlist periodicamente [min]:Salva Music StoreScansione dei file in corsoCercaCerca in:Ricerca il Music StoreCerca la PlaylistRicerca...SelezionaSeleziona una font...Seleziona tuttoSeleziona tutte le tracce nella playlist (Clicca con il tasto destro del mouse per il menù)Seleziona cartellaSeleziona filePrima seleziona, poi chiudi la finestraNessuna selezioneFile selezionato:Trasmetti al dispositivo iFPVolumi singoliImposta sottotitoloImposta velocità del lettoreImpostazioniMostra AqualungMostra valore RVAMostra la traccia attiva in grassettoMostra il pulsante di chiusura sul tabMostra file e cartelle nascoste nel percorso di scelta del fileMostra il titolo della canzone nella barra del titolo della finestra principaleMostra dimensione del file nella barra di statoMostra lunghezza della tracciaModalità ShuffleCanale singoloAmpiezzaScelta SkinSupporto interfaccia, look & feel, GUI hacks: Contatore - Cifre piccoleSoftwareCanzone nella playlist: Info canzone: Titolo canzone: Ordina artisti perOrdina registrazione perFile audio (*.wav, *.aiff, *.au, ...)SorgenteFile sorgente:Barra di stato: Pendenza [dB/dB]:StereoFermaStruttura:Nome della sottocartella lunghezza limite:Sottoponi una interogazione del CD al database CDDB...Inserisci una nuova voceDemanda la ricerca del documento al database CDDB...Sottoscrivi un nuovo feedSottotitoloL'operazione ha avuto successoSupporto Systray Tag del file con i metadatiTag da aggiungere quando viene creato/aggiornato un file MPEG:Cartella di destinazione per i file rippatiCartella "obiettivo":File "obiettivo":TestoL'indirizzo e-mail indicato non è valido.Le informazioni in basso sono riportate dal driver e potrebbero non riflettere le attuali capacità del dispositivo.Il file selezionato sarà cancellato dal disco. Nessun recupero sarà possibile dopo questa operazione. Sei sicuro di voler continuare?La canzone selezionata presenta un formato non supportato dal lettore. Vuoi continuare?Lo Store specificato è stato già aggiunto alla lista.Ci sono cambi non salvati al file dei metadatiQuesto binario Aqualung è compilato con:Questo CD non contiene informazioni di tipo CD-Text.This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.Timeout per socket I/O:TitoloIl tittolo sembra essere scritto tutto a lettere minuscole. Vuoi continuare?Il titolo sembra essere scritto tutto a lettere minuscole. Vuoi continuare?Formato del titoloTitolo:Aggiungi effetto LADSPAVisualizza Music StoreVisualizza playlistTotaleCampioni totali:Totale: TracciaTraccia N.roCommento tracciaLunghezza tracciaNome tracciaNumero tracciaTitoli tracciaTraccia:TracceTraduttori:Tipo:URL:Ucraino: Impossibile aprire il fileImpossibile rimuovere il file %d .Impossibile rimuovere i file %d .Annulla chiusura tabInaspettata fine della stringa dopo il carattere '?'.Minimizza in contemporanea la finestra principale e il Music StoreSconosciutoAlbum sconosciutoArtista sconosciutoRegistrazione sconosciutaTraccia sconosciutaDisco sconosciutoErrore sconosciutoNumero di tentativi illimitati su letture falliteNon misuratoSolo tracce molto lungheNon riconosciutoSenza titoloAggiorna tutti i feedAggiorna feedAggiorna i metadati del fileAggiornamento metadati del file...Aggiornamento in corso...Utilizza solo il semplice nome invece dell'intero percorso se nessun informazione (metadato) è disponibile.Utilizza valori opportuni del valore RVA [dB]Usa solo il database localeCodifica VBRVendorVendor:Verifica integrità dei datiVersioneNome visibile:Livello volume:Volume: %sAvvisami se il Window Manager non supporta la system trayAttenzioneWavPack WavPack (*.wv)API Sound Win32 Scrivi CD-RScrivi CD-RWScrivi DVD+RScrivi DVD+RWScrivi DVD-RScrivi DVD-RAMScrivi DVD-RWScrittura in corsoAnnoAnno:Devi indicare un indirizzo e-mail per il server CDDB.Necessiti di riavviare Aqualung affinché i seguenti cambi abbiano effetto:_Annullato_Aggiungi i file..._Naviga..._Configura_Download_Uploadartistaartistimigliorebit doublebit floatbit con segnobit senza segnovalutazione in corso...giornogiornidrivedrivesCodificavelocefeedfeedcampo:Gestore dispositivo iFP (modalità download)Gestore dispositivo iFP (modalità upload)Driver supporto iRiver iFP vocevocietichetta canzoninuova vocenuove vocirregistrazioneregistrazioniroot / artista / artista / artista / registrazione / tracciaroot / artista / artista / registrazione / tracciaroot / artista / registrazione / tracciaroot / registrazione / tracciarwsecondisndfile (WAV) sndfile (WAV, AIFF, etc.) tag:tracciatraccenon raggiungibileaqualung-0.9beta11/src/po/ja.mo0000644000175000001440000023275411331334313013256 00000000000000$,<8P9P4UPP/Q+MRFyT2U5V)X[X >ZIZRZhZ ~ZZZZZZZ ZZO[T[[[b[ i[ t[[[ [[ [[ [ [ [ [ \ \\3\J\b\t\\ \\\\ \\\\\\] ] !] ,]6]>]&X] ] ]9] ]]]^(^&B^ i^^^^^^^_'_E_^_d_ u_4____ __ _ _`A`A]` `/``hapbbb>b>b $c0c Hc(Uc~cc(ccRc$d -d 8dCdLd$hdRd!d&e")eLege}eeee e eeee e;f H S ] h s  Ð֐ ((>.g  ̑  Ò˒   , : G T _ m y $͓ G* r  ͔ޔ'E[4qҕ! 7 ANR Ycu  ɖ  (-@P-_ ! ȗח ޗ % 6@A И  *: CQa02ʙ) '+Ht #Ț ͚&ښ , 8EU&e  Лכܛ  +I![} ǜ ߜ7!$F Xe5jj Q7F/`&-  Ģ=բ=QXt ģ ң  * KQ Vbv#ޤ  .5<2r ,  % 6BW oC{ ٦( 9FMUks :V ?b ʨ ֨  9KW é Ωة  !-16<CLQV\"c ªǪͪ ֪0'"Ji ƫ̫ ӫ߫mfXڭ;j{ϸĹ ǻлػ4IoOƼͼԼ&@Udy Žֽ%"&IZt ʾԾ ,BIe{ 3Kӿ;]Q*9'-3UK<!64!k33 *= h!uK $ 0'FnJMI8P5q#'KO^O!6RL3 (%4vL-03"!Vx + 5 R_]0 !A \Bi34 MWYl (+ L\o #lYl   4EX<n *-"'Px|3   *#Gk!|   )1[{_0'8 ` jtG=0$Fk06$;Wv}K (2rQ^#$:h_!!2-T  -#MQZN 3YN(( s52E[w 'F\x< FPa3r!-3E'y''&-=Sp Y*'@9S]- *8!c$-$!$D8c 7G 9F>Nj$$6J [i"y  A#'DWk! !8$L q{'$) .9J R \!i$A*$:'_$*? IPcy39#:+M1y @1P e- BN3j# &*5`sz%9 &3:BRYq!33%3Y`y"J5"Ux/ A.)Xs ? ` p z /() ))3]p4/ $- A M n%| ! %<;Bx ^bxz\W l*y*03 4!? a"maen(! (#A eov! Q(*z   0 $5<Xl E0*E0p9T-0R^K?N=Q]1<9n<H<.Hk"   I( Cr       & ,2 %_ % &  & 6 6J   =       ! %:  ` El   #     ) ? U l       '. Vc99B6 = J Taq*  5K^ t 39"mc-$C h!u   5 V w>307hx0 !8Wh  (!  %3I$Pu5.(;W^f|  ]-Ie6{-*1Mip3$HO6??BIb.x @3Fap!- $7O cpw,* 1+]|"' N" -q "   3 !!qK"B"b#Kc#V#>$<E$$'' ='J'!]'I'I' ((!(J(!f(((( ((((( )) 7) E) R)6]) ))))6)6*!F*:h*'****++I0+Fz+ ++K+ -,7,S,i,|,,$,', ,p -%|------.3. G. T.b.~.. ...c.H/O/X/g/]/H0`0u0000000 11Y1Vp1 111 22%2<2O2b2 i2 t2 ~2 2222 2 222 2 22@ 3>N3$3 3 3333 3 4f4Q{4<4' 5255595'S5{55 5 5 5*5RY_sS?3V2(\J""`!${C 8{-'&V5/%.sa,-PUK 5~q B}LwwrUHY{X1z#(k eP*H@g8=b|k?cs[f*S,^o2B+B StD?h tx|~&yvdx=(Fk]>; U&GTe\ +k 64%4WoZP_|: mDCJ< ;!>lN/Dy^dJZ*^#:@m81dFp9_p`76OlLgv}n)GRidYbFha!B l|'5 # yMaO\Qft}v@/c3 08 ;{Nz1rXOP^bTW7\]LWCa:c@NDu"]MnRE`xhre(rZEo/6ijK'X<wp~.Lg:OjJ2F?.5.jVE`TX1f>pmQ"= A9zV)UA~<$qH3[jnE%Z GG,Y06u+ sQ4+&; $K[$q*3'Sz_i< -Q9 wIMA=l}gI02#n)yqfmIb]TMWK%i u,!A)CN9vo7Ic4-u>hteHR[ x70 Maximum number of retries: Destination directory is not read-write accessible! Here you should enter a comma-separated list of domains that should be accessed without using the proxy set above. Example: localhost, .localdomain, .my.domain.com Most drives let Aqualung know when a CD has been inserted or removed by providing a 'media changed' flag. However, some drives don't set this flag properly, and thus it may happen that a newly inserted CD remains unnoticed to Aqualung. In such cases, enabling this option should help. Set the drive speed for CD playing in CD-ROM speed units. One speed unit equals to 176 kBps raw data reading speed. Warning: not all drives honor this setting. Lower speed usually means less drive noise. However, when using Paranoia error correction modes for increased accuracy, generally much larger speeds are required to prevent buffer underruns (and thus audible drop-outs). Please note that these settings do not apply to CD Ripping, which always happens with maximum available speed and with error correction modes manually set before every run. The Music Store you selected has a matching Artist and Album, already containing some tracks. If you press OK, these tracks will be removed. The files themselves will be left intact, but they will be removed from the destination Music Store. Press Cancel to get back to change the Artist/Album or the destination Music Store. The file you enter/choose here will set the Lua program to use to format the title. See the Aqualung manual for details. Here is a quick example of what you can use in the file: function playlist_title() return m('artist') .. '-' .. m('title') .. ' (' .. m('album') .. ') (' .. i('filename') .. ')' end The string you enter here will be parsed as a command line before parsing the actual command line parameters. What you enter here will act as a default setting and may or may not be overridden from the 'real' command line. Example: enter '-o alsa -R' below to use ALSA output running realtime as a default. The template string you enter here will be used to construct a single title line from an Artist, a Record and a Track name. These are denoted by %%%%a, %%%%r and %%%%t, respectively. The template string you enter here will be used to construct the filename of the exported files. The Artist, Record and Track names are denoted by %%%%a, %%%%r and %%%%t. The track number and format-dependent file extension are denoted by %%%%n and %%%%x, respectively. The flag %%%%i gives an identifier which is unique within an export session. (%.1f MB) (%d/%d) (capacity = %.1f MB) Free space (%.1f MB) Selected: out L out R% of standard deviation% of standard deviation :%.1f MB / %.1f MB%d / %d directories%d / %d files%d dB%d of %d songs have format unsupported by your player. Do you want to proceed?%d%% L%d%% R%ld Hz(Untitled)(audio only)(choose a category)(error loading image)(no comment)(no description)(no image)(none)*File info*Music Store100 pixels200 pixels300 pixels50 pixelsDevice statusLocal directoryRemote directorySongs infoTransfer progressA large, coloured fishALSA Audio APEAbortAbort ongoing updateAborted...AboutAbstractAccessAction:Active song in playlist: AddAdd ArtistAdd RecordAdd TrackAdd URLAdd all items to playlistAdd all items to playlist (Album mode)Add directoryAdd filesAdd files to playlist (Press right mouse button for menu)Add item...Add mouse button commandAdd new artist to this store...Add new artist...Add new items to playlistAdd new items to playlist (Album mode)Add new record to this artist...Add new record...Add new track to this record...Add new track...Add to CommentsAdd to Music StoreAdd to playlistAdd to playlist (Album mode)Add year to the comments of new recordsAdding files to PlaylistAlbumAlbum Sort OrderAlbum imageAlbum mode is the default when adding entire recordsAlbum:AllAll Audio FilesAll FilesAll Playlist FilesAll tracksAll wordsAlways show the tab barAn error occurred while attempting to connect to the CDDB server.An error occurred while submitting the record to the CDDB server.AppearanceApply averaged RVA to tracks of the same recordAqualung is compiled with system tray support, but the status icon could not be embedded in the notification area. Your desktop may not have support for a system tray, or it has not been configured correctly.Aqualung is compiled without LADSPA plugin support. See the About box and the documentation for details.Aqualung is compiled without Sample Rate Converter support. See the About box and the documentation for details.Aqualung playlist (*.xml)ArtistArtist appears to be in all lowercase. Do you want to proceed?Artist appears to be in all uppercase. Do you want to proceed?Artist nameArtist name (lowercase)Artist namesArtist/Album already existing, not emptyArtist/performerArtist:Ask for confirmation when removing itemsAttached PictureAttached Picture frame with no image set! Please set an image or remove the frame.Audio CDAudio dataAudiophileAuthors:Auto-check interval [hour]:Auto-create tracks from these files:Automatic update has been disabled for all feeds in the Podcasts store popup menu.Automatically add CDs to PlaylistAutomatically remove CDs from PlaylistAutomatically roll to active trackAutomatically update feedsAvailable connectionsAvailable pluginsAvailable skinsAverageBPMBack coverBalance: %sBand/OrchestraBand/artist logotypeBand/orchestraBandwidth:Batch update & encode (mass tagger, CD ripper, file export)Batch-update file metadata...BatteryBeginBibliographyBig timer: Binary ObjectBitrate [kbps]:BrowseBuild / Update store from filesystem...Build version: Build/Update storeBuilding store from filesystemBurn ProofButtonCC2 Error CorrectionCD AudioCD drive speed:CDDA (Audio CD) support CDDBCDDB (not available)CDDB lookupCDDB queryCDDB query for this CD...CDDB query for this record...CDDB server:CDDB support CDDBP (port 888)Calculate RVACalculate volumeCalculate volume (recursive)Calculating volume levelCannot write to selected directory. Please select another directory.CapitalizationCapitalize: Case sensitiveCatalog NumberCategoryCategory:ChangeChange balanceChange current songChange song positionChange volumeChannel count:Channels:Clear connectionsClear listClick here to set mouse buttonCloseClose other tabsClose tabClose trayClose window when completeClose window when transfer completeCollapse all itemsColorsColumnCombine play and pause buttonsCommandCommentCommentsComments:Commercial InformationComposerCompressed modules (*.bz2)Compressed modules (*.gz)Compressed modules (*.gz, *.bz2)Compression level:Compression: Extra HighCompression: FastCompression: HighCompression: InsaneCompression: NormalConductorConnect via HTTP proxyConnecting to CDDB server...Connection timeout [sec]:ContactContent GroupConversion error in field %s: '%s' does not conform to format '%s'!Conversion to target charset failedConvert underscore to spaceCopyCopyrightCopyright/Legal InformationCore design, engineering & programming: Correct existing recordCould not load image from: %sCover artCreate a new directoryCreate directoryCreate empty storeCreate empty store...Create subdirectories for albumsCreate subdirectories for artistsCurrent file: Cut selectedDSPDateDebut AlbumDecoding support:Default cover width:Delete downloaded items from the filesystemDescriptionDescription:DestinationDetect media changeDevice is busy. (Aqualung was unable to claim its interface.)Device is not responding. Try jiggling the handle.Device path:Direct connection to the InternetDirectory '%s' will be removed with its entire contents. Do you want to proceed?Directory drivenDirectory nameDirectory name (lowercase)Directory structureDisable all pluginsDisable control buttons reliefDisable manual ejectDisable skin supportDiscDisc infoDisc info...Discard changesDo not closeDo not exitDo not magnify images with smaller widthDo not reencode files matching wildcard:Do not reencode files already being in the target formatDo nothingDo you want to save store "%s" before removing from Music Store?Do you want to save the store before removing?Don't show cover thumbnail in the main windowDoneDownload directory:Downloading %d/%d (%d%%) ...Drag and drop entries in the list to set the feed order in the Music Store.Drag and drop entries in the list below to set the column order in the Playlist.Drive infoDrive info...Drop statistical aberrations based onDual channelDuration:During performanceDuring recordingEAN/UPCEdit ArtistEdit RecordEdit StoreEdit TrackEdit artist...Edit feedEdit feed settingsEdit item...Edit record...Edit store...Edit track...EjectEmail address for submission:Embed playlist into main windowEmphasis:Emphasis: noneEmphasis: reservedEnable Music Store tree node iconsEnable all pluginsEnable playback RVAEnable rules hintEnable statusbarEnable statusbar in Music StoreEnable statusbar in playlistEnable systrayEnable toolbarEnable toolbar in Music StoreEnable tooltipsEnable tree node iconsEnabledEncoded byEncoding TimeEncoding support:Enqueue playlistErrorError converting field %s to Year: '%s' is not an integer number!Error in format stringError in title format stringExact matches onlyExclude files matching wildcardExpand Stores on startupExpected '}' after '{', but end of string found.Export all items...Export artist...Export filesExport item...Export new items...Export record...Export store...Export track...Exporting filesExtended Title Format Files (*.lua)Extended data:FLAC PicturesFailed to set metadata for the following files:Failed to write metadata to file. Reason: %sFileFile "%s" does not exist or your write permission has been withdrawn. Check if the partition containing the store file has been unmounted.File '%s' will be removed. Do you want to proceed?File OwnerFile TypeFile format:File icon (32x32 PNG)File icon (other)File infoFile info...File is not writableFile name: File:FilenameFilename template:Filename:Files selected for removalFilesystemFilterFirst word onlyFollows the directory structure to identify the artists and records. The files are added on a record basis.FontsForce TOC re-read on every drive scanForce case: Force other letters to lowercaseFormatFormat:Free Lossless Audio Codec (*.flac)Free Lossless Audio Codec (FLAC) Free spaceFrench: Front coverGeneralGeneric StreamMetaGenreGenre:German: Graphics:HTTP (port 80)Hard reset deviceHelpHide AqualungHide comment paneHide the Music Store comment paneHomepage:Horizontal mouse wheel:Hungarian: IDID3v1ID3v2ISBNISRCIcy-DescriptionIcy-GenreIcy-NameIdleIllustrationImplicit command lineImport Comment tagImport Replaygain tag as manual RVAImport as ArtistImport as RVAImport as RecordImport as Sort KeyImport as TitleImport as Track No.Import as YearIn any caseInclude only files matching wildcardIndependentIndexInitial keyInputsInstrumentsInstruments:Internal errorInternetInternet Radio Station NameInternet Radio Station OwnerInterpreted/RemixedIntroplayInvalid 'Genre' field valueInvalid 'Track no.' field valueInvert current stateInvert selectionInvolved PeopleIt is very likely that the year is wrong. Do you want to proceed?Italian: JACK Audio Server JACK Port SetupJACK connection lostJACK has either been shutdown or it disconnected Aqualung because it was not fast enough. All you can do now is restart both JACK and Aqualung.JACK port setupJapanese: Joint stereoKeep main window always on topKey: LADSPA patch builderLADSPA plugin processingLADSPA plugin support LAME (MP3) LAVC (AC3, AAC, WavPack, WMA, etc.) LAVC audio/video filesLabel CodeLanguageLayer ILayer IILayer IIILead artist/performerLeaflet pageLeft and right mouse buttons are reserved.Left buttonLengthLength:LicenseLimitsLinear threshold [dB]Linear threshold [dB] :Listening environment:Living roomLoad playlistLoad playlist in new tabLoad settings from Music Store fileLocal CDDB directory:LocationLocation and filenameLogo, icons: Loop playback support Loop range: %d-%d%%Loop range: %d-%d%% [%s - %s]Lua (programmable title formatting) support Lyricist/Text WriterLyricist/text writerMIME type: %sMOD Audio (MOD, S3M, XM, IT, etc.) MONOMP3 Playlist (*.m3u)MPEG Audio (*.mp3, *.mpa, *.mpega, ...)MPEG Audio (MPEG 1-2.5 Layer I-III) MPEG StreamMetaMain windowMatches:Maximum number of items:Maximum number of retries:Maximum space to use [MB]:MediaMemory allocation errorMetadataMetadata editor (File info dialog)Middle buttonMiscellaneousMode:Model:Module infoModules (*.xm, *.mod, *.it, *.s3m, ...)Monkey's Audio Codec Monkey's Audio Codec (*.ape)MoodMount RainierMouse buttonMouse buttonsMouse wheelMovie/video screen captureMultimedia Playlist (*.pls)Musepack Musepack (*.mpc)Musepack ReplayGainMusic StoreMusic Store Files (*.xml)Music Store: Musician CreditsMuteNULLNameName to sort by:Name transformationName:New tabNextNext songNo discNo matching record found.No metadata support for this formatNo outputNo proxy for:No suitable iRiver iFP device found. Perhaps it is unplugged or turned off.No.Noisy workshopNoneNone of the selected songs has format supported by your player. Do you want to proceed?Note: pre-existing tags will be updated even though they might not be checked here.OSS Audio OfficeOfficial Artist WebsiteOfficial Audio File WebsiteOfficial Audio Source WebsiteOfficial Radio Station WebsiteOgg Speex Ogg Speex (*.spx)Ogg Vorbis Ogg Vorbis (*.ogg)Ogg Xiph CommentsOne or more stores in Music Store have been modified. Do you want to save them before exiting?One song has format unsupported by your player. Do you want to proceed?Only if unmeasuredOpenBSD compatibility, metadata tweaks: Optional features:OrganizationOriginal AlbumOriginal ArtistOriginal FilenameOriginal LyricistOriginal Release TimeOtherOutputOutput driver support:Output:OutputsOverall: Override skin settingsParanoiaParanoia error correctionPart Of A SetPathPaths must either be absolute or starting with a tilde, which will be expanded to the user's home directory. Drag and drop entries in the list to set the store order in the Music Store.Paths must either be absolute or starting with a tilde.Paths to Music Store databasesPatterns:PausePaymentPerform overlapped readsPerformerPerformer Sort OrderPicture type:PlayPlay CD AudioPlay/PausePlay/Pause songPlay/Stop songPlayback RVAPlayback RVA is currently disabled. Do you want to enable it now?PlaylistPlaylist DelayPlaylist column orderPlaylist: Please enter a new name.Please enter directory name.Please select a Music Store database.Please select a Programable Title Format File.Please select a local path.Please select at least one valid song from playlist.Please select the audio file for this track.Please select the audio files for this record.Please select the directory for exported files.Please select the directory for ripped files.Please select the download directory for this podcast.Please select the root directory.Please select the xml file for this store.Please specify the file to load the image from.Please specify the file to load the playlist from.Please specify the file to save the image to.Please specify the file to save the playlist to.Podcast URL:Podcast support PodcastsPort:Position: %d%%Post Fader (after Volume & Balance)Pre Fader (before Volume & Balance)Predefined transformationsPreviousPrevious songProcessing metadataProcessing:ProducedProfile: BraindeadProfile: InsaneProfile: RadioProfile: StandardProfile: TelephoneProfile: ThumbProfile: XtremeProgrammable title format fileProgramming, GUI engineering: ProgressProgress:Protocol for querying (direct connection only):Proxy host:Proxy settingsPublication RightPublisherPublisher's Official WebsitePublisher/studio logotypePulseAudio Put control buttons at the bottom of playlistQuitRVARVA for Unmeasured Files [dB] :RVA valuesRead CD+GRead CD-DARead CD-RRead CD-RWRead DVD+RRead DVD+RWRead DVD-RRead DVD-RAMRead DVD-ROMRead DVD-RWRead ISRCRead MCNRead Mode 2 Form 1Read Mode 2 Form 2Read multiple sessionsReadingReading fileReally remove "%s" from the Music Store?Really remove '%s' from the Music Store?Really remove store "%s" from the Music Store?ReasonRecordRecord DateRecord LocationRecord nameRecord name (lowercase)Record titlesRecording location/studioRecursive search from the root directory for audio files. The files are processed independently, so only metadata and filename transformation are available.Reference volume [dBFS] :RefreshRegexp matches empty stringRegexp:Regular expressionRelatedRelease TimeRemoveRemove ArtistRemove RecordRemove StoreRemove TrackRemove allRemove artistRemove deadRemove feedRemove file extensionRemove filesRemove item...Remove leading numberRemove non-existing files from storeRemove older items [day]:Remove recordRemove selectedRemove selected songs from playlist (Press right mouse button for menu)Remove storeRemove trackRemoving non-existing filesRenameRename playlistReorder feedsRepeat all songsRepeat current songReplace:ReplayGain Album GainReplayGain Album PeakReplayGain Reference LoudnessReplayGain Track GainReplayGain Track PeakReplayGain tag to use (with fallback to the other): Replaygain_album_gainReplaygain_track_gainReread data for existing tracksReread file metadataRescanResumeRetrieving matches from server...Revision:Right buttonRipRip CDRip CD...Ripping CD tracksRoll to active songRoot path:Running pluginsRussian: SRC Type: STEREOSTOPPINGSample Rate Converter support Sample Rate Converter typeSamplerate:SamplesSamples:SandboxSaveSave all playlistsSave all storesSave and closeSave and restore the playlist on exit/startupSave playlistSave playlist periodically [min]:Save storeScanning filesSearchSearch in:Search the Music StoreSearch the PlaylistSearch...SelectSelect a font...Select allSelect all songs in playlist (Press right mouse button for menu)Select build typeSelect directorySelect filesSelect first and close windowSelect juke-box discSelect noneSelected files:Send to iFP deviceSeparateSet SubtitleSet drive speedSettingsShow AqualungShow RVA valuesShow active track name in boldShow close button in tabShow cover thumbnail for Music Store tracks onlyShow hidden files and directories in file choosersShow song name in the main window's titleShow soundfile size in statusbarShow tags tab first in the file info dialogShow track lengthsShuffle songsSimple view in LADSPA patch builderSingle channelSizeSkin chooserSkin support, look & feel, GUI hacks: Small timers: SoftwareSong in playlist: Song info: Song title: Sort artists bySort records bySound Files (*.wav, *.aiff, *.au, ...)SourceSource file:Start minimizedStatusbar: Steepness [dB/dB] :StereoStopStop adding filesStop adding songsStructure:Subdirectory name length limit:Submit CD to CDDB database...Submit new recordSubmit record to CDDB database...Subscribe to new feedSubtitleSuccessSwedish: SystraySystray support Tag files with metadataTagging TimeTags to add when creating or updating MPEG audio files:Target directory for ripped filesTarget directory:Target file:TestThe email address provided for submission is invalid.The information below is reported by the drive, and may not reflect the actual capabilities of the device.The selected files will be deleted from the filesystem. No recovery will be possible after this operation. Do you want to proceed?The selected song has format unsupported by your player. Do you want to proceed?The specified store has already been added to the list.The store '%s' already exists. Add it on the Settings/Music Store tab.There are unsaved changes to the file metadata.This Aqualung binary is compiled with:This CD does not contain CD-Text information.This button is already assigned.This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.Timeout for socket I/O:TitleTitle FormatTitle Sort OrderTitle appears to be in all lowercase. Do you want to proceed?Title appears to be in all uppercase. Do you want to proceed?Title:Toggle LADSPA patch builderToggle music storeToggle playlistTotalTotal samples:Total: TrackTrack No.Track commentTrack lengthsTrack nameTrack numberTrack titlesTrack:TracksTranslators:Trim leading, tailing and duplicate spacesType:URL:Ukrainian: Unable to open fileUnable to remove %d file.Unable to remove %d files.Undo close tabUnexpected end of string after '?'.United windows minimizationUnknownUnknown AlbumUnknown ArtistUnknown RecordUnknown TrackUnknown conversion type character found after '%%%%'.Unknown conversion type character found after '?'.Unknown discUnknown errorUnlimited retry on failed reads (never skip)UnmeasuredUnmeasured tracks onlyUnrecognizedUntitledUpdate all feedsUpdate feedUpdate file metadataUpdate file metadata...Updating...Use basename only instead of full path if no metadata is available.Use manual RVA value [dB]Use relative paths in store fileUse the local database onlyUser Defined TextUser Defined URLVBR encodingVendorVendor:Verify data integrityVersionVertical mouse wheel:Visible name:Volume level:Volume: %sWarn me if the Window Manager does not support system trayWarningWavPack WavPack (*.wv)When adding new frames, try to set their contents from another tag's equivalent frame.When shuffling, records added in Album mode are played in orderWin32 Sound API Write CD-RWrite CD-RWWrite DVD+RWrite DVD+RWWrite DVD-RWrite DVD-RAMWrite DVD-RWWritingYearYear:You have to provide an email address for CDDB submission.You will need to restart Aqualung for the following changes to take effect:_Abort_Add files..._Browse..._Configure_Download_Uploadartistartistsbestbit doublebit floatbit signedbit unsignedcounting...daydaysdrivedrivesencodingfastfeedfeedsfield:iFP device manager (download mode)iFP device manager (upload mode)iRiver iFP driver support itemitemsnew itemnew itemsrrecordrecordsroot / artist / artist / artist / record / trackroot / artist / artist / record / trackroot / artist / record / trackroot / record / trackrwsecondssndfile (WAV) sndfile (WAV, AIFF, etc.) sndio Audio tag:tracktracksunreachableuse browser window widthProject-Id-Version: Report-Msgid-Bugs-To: POT-Creation-Date: 2010-01-20 07:43+0900 PO-Revision-Date: 2010-01-22 15:40+0100 Last-Translator: YoN Language-Team: Team Puppy Linux Japan MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n != 1); X-Poedit-Language: Japanese リトライの最大数: 目的のディレクトリは読み込み、書き込み可能ではありません! ここでは、上で設定したプロキシを介さずにアクセスする ドメインリスト(カンマ区切り)を入力しなければなりません。 例:localhost, .localdomain, .my.domain.com 大部分のドライブは、 CD が挿入されたり、取り外された時、 Aqualung に「メディアが交換されたこと」を通知します。しかし、いくつかのドライブはこの通知フラグを適切に設定しないため、時々、Aqualung は新しく挿入された CD を認識しないことがあります。そのような場合、このオプションを有効にすると軽減されるでしょう。 CD のドライブ速度は、再生している CD-ROM の速度単位に設定して下さい。速度の1単位は、176kBps 生データの読み出し速度に等しいです。警告: 全てのドライブが、この設定を守るというわけではありません。 通常、速度が低いとドライブのノイズが減ります。しかし、精度を増すために Paranoia エラー訂正モードを使う場合、一般的に、バッファアンダーランを防ぐため、より高い速度が要求されます (そして、このような可聴ドロップアウト)。 これらの設定は CD リッピングに適用されない点に注意して下さい。CD リッピングでは毎回実行する前に、利用できる最高速度やエラー訂正モードを手動で設定します。 選択した Music Store には一致したアーティストとアルバムがあります。そして、すでにいくつかのトラックを含んでいます。 OK を押すと、このトラックは削除されます。ファイル自体は完全なまま残ります。しかし転送先の Music Store から削除されます。アーティスト/アルバムまたは転送先の Music Store の変更に戻るにはキャンセルを押して下さい。 ここで入力/選択をしたファイルはタイトルをフォーマットするために使う Lua プログラムを設定します。詳細は Aqualung マニュアルを確認して下さい。以下はファイルで使える簡単なサンプルです: function playlist_title() return m('artist') .. '-' .. m('title') .. ' (' .. m('album') .. ') (' .. i('filename') .. ')' end ここで入力する文字列は、実際のコマンドラインパラメータを解析する前のコマンドラインとして解析されます。ここで入力したものは、初期設定として作動し、「本当の」コマンドラインから上書きされるか、されないかも知れません。 例: リアルタイムで実行している ALSA 出力をデフォルトで使うには、下に '-o alsa -R' と入力します。 ここに入力するテンプレート文字列は、アーティスト、レコード、トラック名から1つのタイトル行を構成するために使われます。それらは個々に %%%%a, %%%%r と %%%%t, で示されます。 ここで入力するテンプレート文字列は、エクスポートされたファイルのファイル名を構築するために使われます。アーティスト、レコード、トラック名は %%%%a, %%%%r と %%%%t で表示されます。トラック番号と形式依存ファイル拡張子は %%%%n と %%%%x で表示されます。フラグ %%%%i はエクスポートセッションで固有の識別子を与えます。 (%.1f MB) (%d/%d) (容量 = %.1f MB)空きスペース (%.1f MB)選択: 左外 右外標準偏差の % 標準偏差の % :%.1f MB / %.1f MB%d / %d ディレクトリ%d / %d ファイル%d dB%d 中 %d 曲はお使いのプレーヤではサポートされていない形式です。 続けますか?%d%% L%d%% R%ld Hz(タイトルなし)(オーディオだけ)(カテゴリを選択)(イメージの読み込みエラー)(コメントなし)(説明なし)(イメージなし)(なし)*ファイル情報*Music Store100 ピクセル200 ピクセル300 ピクセル50 ピクセルデバイス状況ローカルディレクトリディレクトリを削除曲情報転送進行状況大きな色付きの魚ALSA オーディオ APE中止進行中の更新を中止中止...このソフトについて要約アクセスアクション:プレイリストのアクティブな曲: 追加アーティストを追加レコードを追加トラックを追加URL を追加プレイリストに全てのアイテムを追加プレイリストに全てのアイテムを追加 (アルバムモード)ディレクトリを追加ファイルを追加ファイルをプレイリストに追加 (マウスの右ボタンを押すとメニュー)アイテムを追加...マウスボタンにコマンドを追加このストアに新しいアーティストを追加...新しいアーティストを追加...プレイリストに新しいアイテムを追加プレイリストに新しいアイテムを追加 (アルバムモード)このアーティストに新しいレコードを追加...新しいレコードを追加...このレコードに新しいトラックを追加...新しいトラックを追加...コメントに追加Music Store に追加プレイリストに追加プレイリストに追加 (アルバムモード)新しいレコードのコメントに年を追加ファイルをプレイリストに追加アルバムアルバムの並び替え順序アルバム画像全レコードを追加する時はアルバムモードがデフォルトアルバム:全て全てのオーディオファイル全てのファイル全てのプレイリストファイル全てのトラック全ての単語常にタブバーを表示CDDB サーバに接続しようとしてエラーが起こりました。CDDB サーバにレコードを送信中にエラーが起こりました。外観同じレコードのトラックに平均 RVA を適用Aqualung はシステムトレイを有効にしてコンパイルされています。しかし、ステータスアイコンを通知領域に表示できませんでした。お使いのデスクトップは、システムトレイをサポートしていないか、正しく構成されていません。Aqualung は LADSPA プラグインサポートなしでコンパイルされています。 詳細は「このソフトについて」とドキュメントをご覧下さい。Aqualung はサンプルレート変換サポートなしでコンパイルされています。 詳細は「このソフトについて」とドキュメントをご覧下さい。Aqualung プレイリスト (*.xml)アーティストアーティストは全て小文字で表示されます。 続けますか?アーティストは全て大文字で表示されます。 続けますか?アーティスト名アーティスト名 (小文字)アーティスト名アーティスト/アルバムは既に存在します。空ではありませんアーティスト/演奏者アーティスト:アイテムを削除する時に確認すを要求添付画像添付画像フレームは画像が設定されていません! 画像を設定するかフレームを削除して下さい。オーディオ CDオーディオデータオーディオファン(Hi-Fi愛好家)作者:自動チェックの間隔 [時間]:次のファイルからトラックを自動作成:ポッドキャストストアポップアップメニューの 全てのフィードの自動更新は無効です。CD をプレイリストに自動的に追加CD をプレイリストから自動的に削除自動的にアクティブなトラックへ移動フィードを自動的に更新利用できる接続利用できるプラグイン利用できるスキン平均BPM裏表紙バランス: %sバンド/オーケストラバンド/アーティストロゴタイプバンド/オーケストラ帯域幅:バッチ更新とエンコード (mass tagger、CD リッパ、ファイルエクスポート)ファイルメタデータをバッチ更新...バッテリー開始目録大きいタイマ: バイナリ オブジェクトビットレート [kbps]:ブラウズファイルシステムからストアを、ビルド / 更新...ビルドバージョン: ストアをビルド/更新ファイルシステムからストアをビルドバッファーアンダーラン防止 (Burn Proof)ボタンCC2 エラー訂正CD オーディオCD ドライブ速度:CDDA (Audio CD) サポート CDDBCDDB (利用できません)CDDB 参照CDDB 問い合わせこの CD を CDDB に問い合わせ...このレコードのCDDB問い合わせ...CDDB サーバ:CDDB サポート CDDBP (ポート 888)RVA を計算ボリュームを計算ボリュームを計算 (rekursiv)音量レベルの計算中選択したディレクトリに書き込めません。別のディレクトリを選択して下さい。大文字にする先頭文字を大文字:大文字小文字を区別カタログ番号カテゴリカテゴリ:変更バランスの変更曲の変更再生位置の変更音量の変更チャンネル数:チャンネル:接続をクリアリストをクリアマウスボタンを設定するにはここをクリック閉じる他のタブを閉じるタブを閉じるトレイを閉じる完了したらウィンドウを閉じる転送完了後、ウィンドウを閉じる全てのアイテムを折りたたむ色列再生ボタンと一時停止ボタンを一体化コマンドコメントコメントコメント:コマーシャル情報作曲者圧縮モジュール (*.bz2)圧縮モジュール (*.gz)圧縮モジュール (*.gz, *.bz2)圧縮レベル:圧縮: 超高音質 (Extra High)圧縮: 高速 (Fast)圧縮: 高音質 (High)圧縮: 正気でない (Insane)圧縮: 標準 (Normal)指揮者HTTP プロキシ経由で接続CDDB サーバに接続しています...接続タイムアウト [秒]:コンタクトコンテンツグループフィールド %s で変換エラー: '%s' はフォーマット '%s' に準拠しません!ターゲット文字セットの変換に失敗アンダースコアを空白に変換コピー著作権著作権/法律情報コアデザイン、エンジニアリングとプログラミング: 既存のレコードを修正ここからイメージを読み込めませんでした: %sジャケット画像新しいディレクトリを作成ディレクトリを作成空のストアを作成空のストアを作成...アルバムのサブディレクトリを作成アーティストのサブディレクトリを作成現在のファイル:選択範囲を切り取るDSP (デジタル信号処理)日付デビューアルバムデコードサポート:デフォルトカバー幅:ファイルシステムからダウンロードしたアイテムを削除説明説明:行き先メディアの変更を検出デバイスがビジーです。 (Aqualung はそのインターフェースを取得できませんでした。)デバイスは応答がありません。 ハンドルを軽く動かして見て下さい。デバイスのパス:インターネットに直接接続ディレクトリ '%s' は全てのコンテンツを含めて削除されます。 続けますか?ディレクトリ優先ディレクトリ名ディレクトリ名 (小文字)ディレクトリ構造全てのプラグインを無効コントロールボタンの装飾を無効手動イジェクトを無効スキンサポートを無効ディスクディスク情報ディスク情報...変更を破棄閉じない終了しないより小さい幅で画像を拡大しないワイルドカードに一致する ファイルはエンコードしない:既にターゲットフォーマットにあるファイルは再エンコードしない何もしないMusic Store から削除する前に、ストア "%s" を保存しますか?削除する前にストアを保存しますか?メインウィンドウにジャケットのサムネイルを表示しない完了ディレクトリをダウンロード:%d/%d (%d%%) をダウンロード中...Music Store のフィード順を設定するには リストにエントリをドラッグアンドドロップ。プレイリストの列順を設定するには エントリを下のリストにドラッグアンドドロップしてください。ドライブ情報ドライブ情報...統計的収差を下げるデュアルチャンネル演奏時間:演奏中レコーディング中EAN/UPCアーティストを編集レコードを編集ストアを編集トラックを編集アーティストを編集...フィードを編集フィード設定を編集アイテムを編集...レコードを編集...ストアを編集...トラックを編集...イジェクト送信用メールアドレス:プレイリストをメインウィンドウに埋め込むEmphasis:Emphasis: なしEmphasis: 予約Music Store ツリーノードアイコンを有効全てのプラグインを有効RVA 再生を有効ルールヒントを有効ステータスバーを有効Music Store でステータスバーを有効プレイリストにステータスバーを有効システムトレイを有効にするツールバーを有効Music Store でツールバーを有効ツールチップを有効ツリーノードアイコンを有効有効エンコードエンコード時間エンコードサポート:待ちプレイリストエラーフィールド %s を年に変換中にエラー: '%s' は整数ではありません!文字列のフォーマットにエラータイトル形式文字列にエラー完全一致のみワイルドカードに一致するファイルを除外起動時にストアを展開'{' の後に '}' が必要です。しかし文字列の終わりが見つかりました。全てのアイテムをエクスポート...アーティストをエクスポート...ファイルをエクスポートアイテムをエクスポート...新しいアイテムをエクスポート...レコードをエクスポート...ストアをエクスポート...トラックをエクスポート...エクスポートファイル拡張タイトルフォーマットファイル (*.lua)拡張データ:FLAC 画像以下のファイルのメタデータ設定に失敗:メタデータのファイルへの書き込みに失敗。 理由: %sファイルファイル "%s" は存在していないか、書き込みができません。storeファイルを含むパーティションが既にアンマウントされてないかチェックして下さいファイル '%s' は削除されます。 続けますか?ファイルのオーナーファイルタイプファイルフォーマット:ファイルアイコン (32x32 PNG)ファイルアイコン (その他)ファイル情報ファイル情報...ファイルは書き込み可能ではありませんファイル名:ファイル:ファイル名ファイル名テンプレート:ファイル名:削除選択したファイルファイルシステムフィルタ最初の単語だけアーティストとレコードを識別するためにディレクトリ構造をたどります。 レコードを基準にファイルを追加します。フォントドライブスキャン毎に強制的に TOC を再読み込み大文字小文字を強制適用: 他の文字を小文字に強制適用フォーマットフォーマット:FLAC 可逆圧縮 (*.flac)Free Lossless Audio Codec (FLAC) 空きスペースフランス語: 表紙一般汎用ストリームメタジャンルジャンル:ドイツ語: グラフィックス:HTTP (ポート 80)デバイスをハードリセットヘルプAqualung を隠すコメント欄を隠すMusic Store のコメント欄を隠すホームページ:水平マウスホイール:ハンガリー語: IDID3v1ID3v2ISBNISRCIcy-説明Icy-ジャンルIcy-名待機中イラスト暗黙的なコマンドラインコメントタグをインポートマニュアル RVA として ReplayGain タグをインポートアーティストとしてインポートRVA としてインポートレコードとしてインポートソートキーとしてインポートタイトルとしてインポートトラック番号としてインポート年としてインポートどんな場合でもワイルドカードに一致するファイルだけを含む独立インデックスイニシャルキー入力楽器楽器:内部エラーインターネットインターネットラジオステーション名インターネットラジオステーション所有者変換/リミックスイントロ再生無効な 'ジャンル' フィールド値無効な 'トラック番号' フィールド値現在の状況を反転選択を反転関係者年が間違っていると思われます。 続けますか?イタリア語: JACK オーディオサーバ JACK ポート設定JACK 接続が失われましたJACK は十分な速度がないので、シャットダウンされたか Aqualung を切断しました。今すぐ JACK と Aqualung を再起動して下さい。JACK ポート設定日本語: ジョイントステレオメインウィンドウを常に一番上にするキー: LADSPA パッチビルダLADSPA プラグイン処理LADSPA プラグインサポート LAME (MP3) LAVC (AC3, AAC, WavPack, WMA, など) LAVC オーディオ/ビデオファイルラベルコード言語レイヤー Iレイヤー IIレイヤー IIIリードアーティスト/演奏者リーフレットページ右ボタンと左ボタンは予約されています。左ボタン長さ長さ:ライセンス限度線形しきい値 [dB]線形しきい値 [dB] :リスニング環境:居間プレイリストを読み込むプレイリストを新しいタブで読み込むMusic Store ファイルから設定を読み込みローカル CDDB ディレクトリ:場所場所とファイル名ロゴ、アイコン: ループ再生サポート ループ範囲: %d-%d%%ループ範囲: %d-%d%% [%s - %s]Lua サポート (プログラム可能なタイトルフォーマット) 作詞者/テキストライタ作詞家/テキストライターMIME タイプ: %sMOD オーディオ (MOD, S3M, XM, IT, など) モノラルMP3 プレイリスト (*.m3u)MPEG オーディオ 非可逆圧縮 (*.mp3, *.mpa, *.mpega, ...)MPEG オーディオ (MPEG 1-2.5 Layer I-III) MPEG ストリームメタメインウィンドウ一致:アイテムの最大数:再試行の最大数:使用する最大容量 [MB]:メディアメモリ割り当てエラーメタデータメタデータエディタ (ファイル情報ダイアログ)中央ボタンその他モード:モデル:モジュール情報モジュール (*.xm, *.mod, *.it, *.s3m, ...)Monkey's オーディオコーデック Monkey's Audio Codec 可逆圧縮 (*.ape)ムードマウント レーニア (Mount Rainier)マウスボタンマウスボタンマウスホイールムービー/ビデオスクリーンキャプチャマルチメディアプレイリスト (*.pls)Musepack Musepack VBR 非可逆圧縮 (*.mpc)Musepack ReplayGainMusic StoreMusic Store ファイル (*.xml)Music Store: ミュージシャン クレジットミュート何のデータも含まれない名前並び替える名前:名前の変換名前:新しいタブ次次の曲CD がありません一致するレコードは見つかりませんでした。この形式をサポートするメタデータはありません出力なしプロキシなし:iRiver-iFP に合うデバイスが見つかりません。 たぶん、接続されていないか電源が切れています。No.やかましい工場なしお使いのプレーヤでサポートされていない形式の曲は選択されていません。 続けますか?メモ: これまでのタグはここでチェックされなくても更新されます。OSS オーディオ オフィス公式アーティストウェブサイト公式音声ファイルウェブサイト公式オーディオソースウェブサイト公式ラジオステーションウェブサイトOgg Speex Ogg Speex 非可逆圧縮 (*.spx)Ogg Vorbis Ogg Vorbis 非可逆圧縮 (*.ogg)Ogg-Xiph コメントMusic Storeの1つ以上のストアが変更されました。 終了前に保存しますか?1曲はお使いのプレーヤではサポートされていない形式です。 続けますか?無制限の時だけOpenBSD 互換、メタデータ調整: オプション機能:組織オリジナルアルバムオリジナルアーティストオリジナルファイル名オリジナル作詞者オリジナル リリース時間 その他出力出力ドライバサポート:出力:出力全般:スキンの設定を無視するParanoiaParanoia エラー訂正セットの一部パスパスは絶対パスかチルダ付きで始まらなければなりません。そしてユーザのホームディレクトリに展開されます。 Music Store にストア順序を設定するにはエントリをリストにドラッグアンドドロップして下さい。パスは絶対パスかチルダ付きで始まらなければなりません。Music Store データベースへのパスパターン:一時停止支払いオーバーラップした読み込みの実行演奏者演奏者の並び替え順序画像タイプ:再生CD オーディオを再生再生/一時停止曲の再生/一時停止曲の再生/停止RVA 再生再生 RVA は現在無効です。 今すぐ有効にしますか?プレイリストプレイリスト遅延列順プレイリストプレイリスト: 新しい名前を入力して下さい。ディレクトリ名を入力して下さい。Music Store データベースを選択して下さい。プログラム可能なタイトル形式のファイルを選択して下さい。ローカルパスを選択して下さい。プレイリストから少なくとも1つ有効な曲を選択して下さい。このトラックのオーディオファイルを選択して下さい。レコード用の音声ファイルを選択して下さい。エクスポートファイルのディレクトリを選択して下さい。リッピングしたファイルのディレクトリを選択して下さい。このポッドキャストのダウンロードディレクトリを選択して下さい。rootディレクトリを選択して下さい。ストア用にxmlファイルを選択して下さい。画像を読み込むファイルを指定して下さい。プレイリストを読み込むファイルを指定して下さい。画像を保存するファイルを指定して下さい。プレイリストを保存するファイルを指定して下さい。ポッドキャストURL:ポッドキャストサポート ポッドキャストポート:ポジション: %d%%ポストフェーダ (AUX 出力を後ろから音量コントロール)プリフェーダ (AUX 出力を前から音量コントロール)定義済み変換前前の曲メタデータの処理中処理中:作成日時プロファイル: 脳死 (Braindead)プロファイル: 正気でない (Insane)プロファイル: ラジオ (Radio)プロファイル: 標準 (Standard)プロファイル: 電話 (Telephone)プロファイル: Thumbプロファイル: 高音質 (Xtreme)プログラム可能なタイトル形式ファイルプログラミング、GUI エンジニアリング: 進行状況進行状況:問い合わせを行うプロトコル (直接接続のみ):プロキシホスト:プロキシ設定出版権出版社出版社公式ウェブサイト出版社/スタジオロゴタイプPulseAudio コントロールボタンをプレイリストの一番下に置く終了RVA無制限ファイルの RVA [dB] :RVA 値CD+G を読み込むCD-DA を読み込むCD-R を読み込むCD-RW を読み込むDVD+R を読み込むDVD+RW を読み込むDVD-R を読み込むDVD-RAM を読み込むDVD-ROM を読み込むDVD-RW を読み込むISRC を読み込むMCN を読み込むMode 2 Form 1 を読み込むMode 2 Form 2 を読み込むマルチセッションを読み込む読み込みファイルの読み取りMusic Store から本当に "%s" を削除しますか?本当に Music Store から '%s'を削除しますか?Music Store から本当にストア "%s" を削除しますか?理由レコード録音日録音場所レコード名レコード名 (小文字)レコードタイトル録音場所/スタジオオーディオファイルをルートディレクトリから再帰的に検索します。 ファイルは独立して処理されるので、メタデータとファイル名の 変換だけができます。基準音量 [dBFS] :更新正規表現に一致する空の文字列正規表現:正規表現関連リリース時間削除アーティストを削除レコードを削除ストアを削除トラックを削除全て削除アーティストを削除存在しないものを削除フィードを削除ファイル拡張子を削除ファイルを削除アイテムを削除...先頭の数値を削除ストアから存在しないファイルを削除古いアイテムを削除 [日]:レコードを削除選択を削除プレイリストから選択した曲を削除 (マウスの右ボタンを押すとメニュー)ストアを削除トラックを削除存在しないファイルの削除リネームプレイリストをリネームフィードを並び替え全ての曲をリピート現在の曲をリピート置換:ReplayGain アルバムゲインReplayGain アルバムピークReplayGain ラウドネス参照ReplayGain トラックゲインReplayGain トラックピーク使用する ReplayGain タグ (他にフォールバック): Replaygain_album_gainReplaygain_track_gain既存のトラックでデータを再読み込みファイルのメタデータを再読み込み再スキャンレジュームサーバから一致を取得しています...リビジョン:右ボタンリッピングCD をリッピングCD をリッピング...CD トラックをリッピングアクティブな曲に移動ルートパス:プラグインを実行ロシア語: SRCタイプ: ステレオ停止中サンプルレート変換サポート サンプルレート変換形式サンプルレート:サンプルサンプル:サンドボックス保存全てのプレイリストを保存全てのストアを保存保存して閉じる終了/起動時にプレイリストを保存/復元プレイリストを保存プレイリストを定期的に保存 [分]:ストアを保存ファイルのスキャン検索検索:Music Store を検索プレイリストを検索検索...選択フォントを選択...全て選択プレイリストの全ての曲を選択 (マウスの右ボタンを押すとメニュー)ビルドタイプを選択ディレクトリを選択ファイルを選択最初に選択してからウィンドウを閉じるジュークボックスディスクを選択何も選択しない選択したファイル:iFP デバイスに送信分離サブタイトルを設定ドライブ速度を設定設定Aqualung を表示RVA 値を表示アクティブなトラック名を太字で表示タブに閉じるボタンを表示Music Store トラックのジャケットサムネイルだけを表示ファイル選択画面で隠しファイル/ディレクトリを表示するメインウィンドウのタイトルに曲名を表示するステータスバーに音声ファイルのサイズを表示ファイル情報ダイアログで最初にタグタブを表示トラック長を表示曲をシャッフルLADSPA パッチビルダでシンプル表示シングルチャンネルサイズスキン選択スキンサポート、ルック&フィール、GUI ハック: 小さいタイマ: ソフトウェアプレイリストの曲: 曲の情報: 曲のタイトル: アーティストを並び替えレコードを並び替え音声ファイル (*.wav, *.aiff, *.au, ...)ソースソースファイル:最小化した状態で開始するステータスバー: 急激度 [dB/dB] :ステレオ停止ファイルの追加を中止曲の追加を中止構造:サブディレクトリ名の 長さ制限:CD を CDDB データベースに送信...新しいレコードを送信CDDBデータベースにレコードを送信...新しいフィードを購読サブタイトル成功スウェーデン語: システムトレイシステムトレイサポート メタデータ付きタグファイルタグ付け時間MPEG オーディオファイルの作成、更新の時に追加するタグ:リッピングしたファイルの保存先ターゲットディレクトリ:ターゲットファイル:テスト送信するメールアドレスが無効です。以下の情報はドライブから報告されたものです。 しかし実際のデバイスの機能を反映していないかもしれません。選択したファイルはファイルシステムから削除されます。この操作後はリカバリできません。 続けますか?選択した曲はお使いのプレーヤではサポートされていない形式です。 続けますか?指定のストアは既にリストに追加されています。ストア '%s' は既に存在します。 それを設定/Music Store タブに追加します。ファイルメタデータに保存していない変更があります。この Aqualung バイナリは次のオプションでコンパイルしています:この CD は CD テキスト情報を含んでいません。このボタンはすでに割り当てられています。This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.ソケット I/O のタイムアウト:タイトルタイトル形式タイトルの並び替え順序タイトルは全て小文字で表示されます。 続けますか?タイトルは全て大文字で表示されます。 続けますか?タイトル:LADSPA パッチビルダを切り替えMusic Store を切り替えプレイリストを切り替え合計合計サンプル:合計: トラックトラック番号トラックコメントトラックの長さトラック名トラック番号トラックタイトルトラック:トラック翻訳者:先頭、末尾をトリミングして空白を複製タイプ:URL:ウクライナ語: ファイルを開けません%d ファイルを削除する事はできません。%d ファイルを削除する事はできません。タブを閉じるを元に戻す'?' の後に予期しない文字列の終わりです。結合したウィンドウの最小化不明不明なアルバム不明なアーティスト不明なレコード不明なトラック'%%%%' の後に不明な変換タイプ文字が見つかりました。'?' の後に不明な変換タイプ文字が見つかりました。不明な CD不明なエラー読み込みに失敗したら無制限に再試行 (スキップしない)無制限無制限トラックだけ認識されませんタイトルなし全てのフィードを更新フィードを更新ファイルメタデータを更新ファイルメタデータを更新...更新中...メタデータが利用できなければ フルパスの変わりにベースネームだけを使います。マニュアル RVA 値を使う [dB]ストアファイルに相対パスを使うローカルデータベースだけを使う指定のテキストを使うユーザ指定のURLVBR エンコードベンダーベンダー:データ整合性の確認バージョン垂直マウスホイール:表示名:ボリュームレベル:ボリューム: %sウィンドウマネージャがシステムトレイをサポートしない時は警告します警告WavPack WavPack (*.wv)新しいフレームを追加するとき、別タグの同じフレームから コンテンツの設定を試して下さい。シャッフルの時は、レコードはアルバムモードに追加された順に再生Win32 サウンド API CD-R に書き込むCD-RW に書き込むDVD-R に書き込むDVD+RW に書き込むDVD-R に書き込むDVD-RAM に書き込むDVD-RW に書き込む書き込み中年年:CDDB へ送信するにはメールアドレスを提供しなければなりません。次の変更を有効にするには Aqualung を再起動する必要があります:中止(_A)ファイルを追加(_A)...ブラウズ(_B)...設定(_C)ダウンロード(_D)アップロード(_U)アーティストアーティスト最高bit doublebit floatbit signedbit unsignedカウント中...日日ドライブドライブエンコード高速フィードフィードフィールド:iFP デバイスマネージャ (ダウンロード モード)iFP デバイスマネージャ (アップロード モード)iRiver iFP ドライバサポート アイテムアイテム新しいアイテム新しいアイテムrレコードレコードルート / アーティスト / アーティスト / アーティスト / レコード / トラックルート / アーティスト / アーティスト / レコード / トラックルート / アーティスト / レコード / トラックルート / レコード / トラックrw秒音声ファイル (WAV) 音声ファイル (WAV, AIFF, など) sndio オーディオ タグ:トラックトラック到達不能ブラウザのウィンドウ幅を使うaqualung-0.9beta11/src/po/ru.mo0000644000175000001440000026745411331334313013317 00000000000000$,<8P9P4UPP/Q+MRFyT2U5V)X[X >ZIZRZhZ ~ZZZZZZZ ZZO[T[[[b[ i[ t[[[ [[ [[ [ [ [ [ \ \\3\J\b\t\\ \\\\ \\\\\\] ] !] ,]6]>]&X] ] ]9] ]]]^(^&B^ i^^^^^^^_'_E_^_d_ u_4____ __ _ _`A`A]` `/``hapbbb>b>b $c0c Hc(Uc~cc(ccRc$d -d 8dCdLd$hdRd!d&e")eLege}eeee e eeee e;f H S ] h s  Ð֐ ((>.g  ̑  Ò˒   , : G T _ m y $͓ G* r  ͔ޔ'E[4qҕ! 7 ANR Ycu  ɖ  (-@P-_ ! ȗח ޗ % 6@A И  *: CQa02ʙ) '+Ht #Ț ͚&ښ , 8EU&e  Лכܛ  +I![} ǜ ߜ7!$F Xe5jj Q7F/`&-  Ģ=բ=QXt ģ ң  * KQ Vbv#ޤ  .5<2r ,  % 6BW oC{ ٦( 9FMUks :V ?b ʨ ֨  9KW é Ωة  !-16<CLQV\"c ªǪͪ ֪0'"Ji ƫ̫ ӫ߫X>QZ7'#K_7 EGS )? T ^4h6 %6%\|#,%:O.c((+(&9 `lp4 4E'V~=Y c"*<MV7AA[M+>'V*~?%AMQ6 4%> %);=M\cLmbrC"bdg!?%.QT!b+Co *A R3`PEDR8c'' 8Te2 H &D [bf8Nm "##1D)V1%'<A,~=<1z !*?*j# #R$w*7@#(d N5-M{! ''@]$z"30I6)qU:II PW8G)(8a03=E"h#.4[42mi]!9#3>#3.WC02."7%Z#NX!bzSV 1 >!_$"%ck#$1'/G#w4%6,-*Z2&E>E2f,M]zB0aLG06'g^#7"3!L*n% t+A>m.H?$Od-6"5/X,&[$qfZnwJg#&"D%g2 #5&\ |$ w W(  "! 7,Bo x. 4 c?"3 %*Jb>8W(84.?4]0(S [ r     !  : :K '  5 B <8 -u  `  0 "C *f  "  % D  :"E.h/ $%2 ; F R0_P  0$?$d&$Aa*'1K(j2h / Pq#'$&@X7n=R7,HuW   $%,Jw--/0] 2+>-G/u#'#=Pn)O2A! >IERCLG) q| |$M6486 *@ *k ,   3  ! ! (!.5!d!4m!!!!bL#O## $ $=+$i$<$$ $!$) %,5%,b% %p% &$&4D&y&8&H&j'z'D'xA(W(Y)ll)b)j<*H*Z*K++bR,_,-&+-R- c-m-L-F-?.V.k.'...!.&./ :/[/z/*/Y/M0h0y0Z000$1D1?U1,1 1U1 $2 /2H<22222222 3333H3k\333384 N4[4`s4`4u555 5555;6!O6$q6'6>77Y8 h8'v8'888%89#-9Q9i9%999.9 : &:)G:Pq:@:;#;C;#; <:!<\<,w<(<$<,< =v-=U=Z=rU>Q>Q?l??H?4?@+@>B@@@@#@*@$A1?AqA)AA A AARAOFB*BBBBB-C.>C$mCmC$DH%D'nD%D DD9D!E 4EBEQEnEE$F8FVF6pF.F"FF0GIG-eG*GGG%GPHFbHHn2I`IOJjRJ,JJ= KHK \KiK8K#KK#K$L8L4VL(L6LLL3M!KMmM MM6M4M NFNQeN*N@N1#OUOnO}OO3O/O$Po7PNP$PQ:QCQQR\SRSITZTNEU?U0UrVAx[[[4[U"\Wx\\2\=]"S] v]] ]]]$]]^^,^ J^ T^_^Yw^^^^,^0"_3S_0_>_8_0`#G`-k`#``T`Q2aa#aaMb0fbbb"bb0c39cmcc;d_ZdNd+ e$5e=Zeee6e f/fCf"^fff g1g:gIgghhhhhhi#i 7iDiKiOSii/jAjajpjjjjj jj)j%k=k[kmkvk}k kkk k k kGkGl/gllllll m mq!mXm?m&,nSn mnznn nnnnn?nRY_sS?3V2(\J""`!${C 8{-'&V5/%.sa,-PUK 5~q B}LwwrUHY{X1z#(k eP*H@g8=b|k?cs[f*S,^o2B+B StD?h tx|~&yvdx=(Fk]>; U&GTe\ +k 64%4WoZP_|: mDCJ< ;!>lN/Dy^dJZ*^#:@m81dFp9_p`76OlLgv}n)GRidYbFha!B l|'5 # yMaO\Qft}v@/c3 08 ;{Nz1rXOP^bTW7\]LWCa:c@NDu"]MnRE`xhre(rZEo/6ijK'X<wp~.Lg:OjJ2F?.5.jVE`TX1f>pmQ"= A9zV)UA~<$qH3[jnE%Z GG,Y06u+ sQ4+&; $K[$q*3'Sz_i< -Q9 wIMA=l}gI02#n)yqfmIb]TMWK%i u,!A)CN9vo7Ic4-u>hteHR[ x70 Maximum number of retries: Destination directory is not read-write accessible! Here you should enter a comma-separated list of domains that should be accessed without using the proxy set above. Example: localhost, .localdomain, .my.domain.com Most drives let Aqualung know when a CD has been inserted or removed by providing a 'media changed' flag. However, some drives don't set this flag properly, and thus it may happen that a newly inserted CD remains unnoticed to Aqualung. In such cases, enabling this option should help. Set the drive speed for CD playing in CD-ROM speed units. One speed unit equals to 176 kBps raw data reading speed. Warning: not all drives honor this setting. Lower speed usually means less drive noise. However, when using Paranoia error correction modes for increased accuracy, generally much larger speeds are required to prevent buffer underruns (and thus audible drop-outs). Please note that these settings do not apply to CD Ripping, which always happens with maximum available speed and with error correction modes manually set before every run. The Music Store you selected has a matching Artist and Album, already containing some tracks. If you press OK, these tracks will be removed. The files themselves will be left intact, but they will be removed from the destination Music Store. Press Cancel to get back to change the Artist/Album or the destination Music Store. The file you enter/choose here will set the Lua program to use to format the title. See the Aqualung manual for details. Here is a quick example of what you can use in the file: function playlist_title() return m('artist') .. '-' .. m('title') .. ' (' .. m('album') .. ') (' .. i('filename') .. ')' end The string you enter here will be parsed as a command line before parsing the actual command line parameters. What you enter here will act as a default setting and may or may not be overridden from the 'real' command line. Example: enter '-o alsa -R' below to use ALSA output running realtime as a default. The template string you enter here will be used to construct a single title line from an Artist, a Record and a Track name. These are denoted by %%%%a, %%%%r and %%%%t, respectively. The template string you enter here will be used to construct the filename of the exported files. The Artist, Record and Track names are denoted by %%%%a, %%%%r and %%%%t. The track number and format-dependent file extension are denoted by %%%%n and %%%%x, respectively. The flag %%%%i gives an identifier which is unique within an export session. (%.1f MB) (%d/%d) (capacity = %.1f MB) Free space (%.1f MB) Selected: out L out R% of standard deviation% of standard deviation :%.1f MB / %.1f MB%d / %d directories%d / %d files%d dB%d of %d songs have format unsupported by your player. Do you want to proceed?%d%% L%d%% R%ld Hz(Untitled)(audio only)(choose a category)(error loading image)(no comment)(no description)(no image)(none)*File info*Music Store100 pixels200 pixels300 pixels50 pixelsDevice statusLocal directoryRemote directorySongs infoTransfer progressA large, coloured fishALSA Audio APEAbortAbort ongoing updateAborted...AboutAbstractAccessAction:Active song in playlist: AddAdd ArtistAdd RecordAdd TrackAdd URLAdd all items to playlistAdd all items to playlist (Album mode)Add directoryAdd filesAdd files to playlist (Press right mouse button for menu)Add item...Add mouse button commandAdd new artist to this store...Add new artist...Add new items to playlistAdd new items to playlist (Album mode)Add new record to this artist...Add new record...Add new track to this record...Add new track...Add to CommentsAdd to Music StoreAdd to playlistAdd to playlist (Album mode)Add year to the comments of new recordsAdding files to PlaylistAlbumAlbum Sort OrderAlbum imageAlbum mode is the default when adding entire recordsAlbum:AllAll Audio FilesAll FilesAll Playlist FilesAll tracksAll wordsAlways show the tab barAn error occurred while attempting to connect to the CDDB server.An error occurred while submitting the record to the CDDB server.AppearanceApply averaged RVA to tracks of the same recordAqualung is compiled with system tray support, but the status icon could not be embedded in the notification area. Your desktop may not have support for a system tray, or it has not been configured correctly.Aqualung is compiled without LADSPA plugin support. See the About box and the documentation for details.Aqualung is compiled without Sample Rate Converter support. See the About box and the documentation for details.Aqualung playlist (*.xml)ArtistArtist appears to be in all lowercase. Do you want to proceed?Artist appears to be in all uppercase. Do you want to proceed?Artist nameArtist name (lowercase)Artist namesArtist/Album already existing, not emptyArtist/performerArtist:Ask for confirmation when removing itemsAttached PictureAttached Picture frame with no image set! Please set an image or remove the frame.Audio CDAudio dataAudiophileAuthors:Auto-check interval [hour]:Auto-create tracks from these files:Automatic update has been disabled for all feeds in the Podcasts store popup menu.Automatically add CDs to PlaylistAutomatically remove CDs from PlaylistAutomatically roll to active trackAutomatically update feedsAvailable connectionsAvailable pluginsAvailable skinsAverageBPMBack coverBalance: %sBand/OrchestraBand/artist logotypeBand/orchestraBandwidth:Batch update & encode (mass tagger, CD ripper, file export)Batch-update file metadata...BatteryBeginBibliographyBig timer: Binary ObjectBitrate [kbps]:BrowseBuild / Update store from filesystem...Build version: Build/Update storeBuilding store from filesystemBurn ProofButtonCC2 Error CorrectionCD AudioCD drive speed:CDDA (Audio CD) support CDDBCDDB (not available)CDDB lookupCDDB queryCDDB query for this CD...CDDB query for this record...CDDB server:CDDB support CDDBP (port 888)Calculate RVACalculate volumeCalculate volume (recursive)Calculating volume levelCannot write to selected directory. Please select another directory.CapitalizationCapitalize: Case sensitiveCatalog NumberCategoryCategory:ChangeChange balanceChange current songChange song positionChange volumeChannel count:Channels:Clear connectionsClear listClick here to set mouse buttonCloseClose other tabsClose tabClose trayClose window when completeClose window when transfer completeCollapse all itemsColorsColumnCombine play and pause buttonsCommandCommentCommentsComments:Commercial InformationComposerCompressed modules (*.bz2)Compressed modules (*.gz)Compressed modules (*.gz, *.bz2)Compression level:Compression: Extra HighCompression: FastCompression: HighCompression: InsaneCompression: NormalConductorConnect via HTTP proxyConnecting to CDDB server...Connection timeout [sec]:ContactContent GroupConversion error in field %s: '%s' does not conform to format '%s'!Conversion to target charset failedConvert underscore to spaceCopyCopyrightCopyright/Legal InformationCore design, engineering & programming: Correct existing recordCould not load image from: %sCover artCreate a new directoryCreate directoryCreate empty storeCreate empty store...Create subdirectories for albumsCreate subdirectories for artistsCurrent file: Cut selectedDSPDateDebut AlbumDecoding support:Default cover width:Delete downloaded items from the filesystemDescriptionDescription:DestinationDetect media changeDevice is busy. (Aqualung was unable to claim its interface.)Device is not responding. Try jiggling the handle.Device path:Direct connection to the InternetDirectory '%s' will be removed with its entire contents. Do you want to proceed?Directory drivenDirectory nameDirectory name (lowercase)Directory structureDisable all pluginsDisable control buttons reliefDisable manual ejectDisable skin supportDiscDisc infoDisc info...Discard changesDo not closeDo not exitDo not magnify images with smaller widthDo not reencode files matching wildcard:Do not reencode files already being in the target formatDo nothingDo you want to save store "%s" before removing from Music Store?Do you want to save the store before removing?Don't show cover thumbnail in the main windowDoneDownload directory:Downloading %d/%d (%d%%) ...Drag and drop entries in the list to set the feed order in the Music Store.Drag and drop entries in the list below to set the column order in the Playlist.Drive infoDrive info...Drop statistical aberrations based onDual channelDuration:During performanceDuring recordingEAN/UPCEdit ArtistEdit RecordEdit StoreEdit TrackEdit artist...Edit feedEdit feed settingsEdit item...Edit record...Edit store...Edit track...EjectEmail address for submission:Embed playlist into main windowEmphasis:Emphasis: noneEmphasis: reservedEnable Music Store tree node iconsEnable all pluginsEnable playback RVAEnable rules hintEnable statusbarEnable statusbar in Music StoreEnable statusbar in playlistEnable systrayEnable toolbarEnable toolbar in Music StoreEnable tooltipsEnable tree node iconsEnabledEncoded byEncoding TimeEncoding support:Enqueue playlistErrorError converting field %s to Year: '%s' is not an integer number!Error in format stringError in title format stringExact matches onlyExclude files matching wildcardExpand Stores on startupExpected '}' after '{', but end of string found.Export all items...Export artist...Export filesExport item...Export new items...Export record...Export store...Export track...Exporting filesExtended Title Format Files (*.lua)Extended data:FLAC PicturesFailed to set metadata for the following files:Failed to write metadata to file. Reason: %sFileFile "%s" does not exist or your write permission has been withdrawn. Check if the partition containing the store file has been unmounted.File '%s' will be removed. Do you want to proceed?File OwnerFile TypeFile format:File icon (32x32 PNG)File icon (other)File infoFile info...File is not writableFile name: File:FilenameFilename template:Filename:Files selected for removalFilesystemFilterFirst word onlyFollows the directory structure to identify the artists and records. The files are added on a record basis.FontsForce TOC re-read on every drive scanForce case: Force other letters to lowercaseFormatFormat:Free Lossless Audio Codec (*.flac)Free Lossless Audio Codec (FLAC) Free spaceFrench: Front coverGeneralGeneric StreamMetaGenreGenre:German: Graphics:HTTP (port 80)Hard reset deviceHelpHide AqualungHide comment paneHide the Music Store comment paneHomepage:Horizontal mouse wheel:Hungarian: IDID3v1ID3v2ISBNISRCIcy-DescriptionIcy-GenreIcy-NameIdleIllustrationImplicit command lineImport Comment tagImport Replaygain tag as manual RVAImport as ArtistImport as RVAImport as RecordImport as Sort KeyImport as TitleImport as Track No.Import as YearIn any caseInclude only files matching wildcardIndependentIndexInitial keyInputsInstrumentsInstruments:Internal errorInternetInternet Radio Station NameInternet Radio Station OwnerInterpreted/RemixedIntroplayInvalid 'Genre' field valueInvalid 'Track no.' field valueInvert current stateInvert selectionInvolved PeopleIt is very likely that the year is wrong. Do you want to proceed?Italian: JACK Audio Server JACK Port SetupJACK connection lostJACK has either been shutdown or it disconnected Aqualung because it was not fast enough. All you can do now is restart both JACK and Aqualung.JACK port setupJapanese: Joint stereoKeep main window always on topKey: LADSPA patch builderLADSPA plugin processingLADSPA plugin support LAME (MP3) LAVC (AC3, AAC, WavPack, WMA, etc.) LAVC audio/video filesLabel CodeLanguageLayer ILayer IILayer IIILead artist/performerLeaflet pageLeft and right mouse buttons are reserved.Left buttonLengthLength:LicenseLimitsLinear threshold [dB]Linear threshold [dB] :Listening environment:Living roomLoad playlistLoad playlist in new tabLoad settings from Music Store fileLocal CDDB directory:LocationLocation and filenameLogo, icons: Loop playback support Loop range: %d-%d%%Loop range: %d-%d%% [%s - %s]Lua (programmable title formatting) support Lyricist/Text WriterLyricist/text writerMIME type: %sMOD Audio (MOD, S3M, XM, IT, etc.) MONOMP3 Playlist (*.m3u)MPEG Audio (*.mp3, *.mpa, *.mpega, ...)MPEG Audio (MPEG 1-2.5 Layer I-III) MPEG StreamMetaMain windowMatches:Maximum number of items:Maximum number of retries:Maximum space to use [MB]:MediaMemory allocation errorMetadataMetadata editor (File info dialog)Middle buttonMiscellaneousMode:Model:Module infoModules (*.xm, *.mod, *.it, *.s3m, ...)Monkey's Audio Codec Monkey's Audio Codec (*.ape)MoodMount RainierMouse buttonMouse buttonsMouse wheelMovie/video screen captureMultimedia Playlist (*.pls)Musepack Musepack (*.mpc)Musepack ReplayGainMusic StoreMusic Store Files (*.xml)Music Store: Musician CreditsMuteNULLNameName to sort by:Name transformationName:New tabNextNext songNo discNo matching record found.No metadata support for this formatNo outputNo proxy for:No suitable iRiver iFP device found. Perhaps it is unplugged or turned off.No.Noisy workshopNoneNone of the selected songs has format supported by your player. Do you want to proceed?Note: pre-existing tags will be updated even though they might not be checked here.OSS Audio OfficeOfficial Artist WebsiteOfficial Audio File WebsiteOfficial Audio Source WebsiteOfficial Radio Station WebsiteOgg Speex Ogg Speex (*.spx)Ogg Vorbis Ogg Vorbis (*.ogg)Ogg Xiph CommentsOne or more stores in Music Store have been modified. Do you want to save them before exiting?One song has format unsupported by your player. Do you want to proceed?Only if unmeasuredOpenBSD compatibility, metadata tweaks: Optional features:OrganizationOriginal AlbumOriginal ArtistOriginal FilenameOriginal LyricistOriginal Release TimeOtherOutputOutput driver support:Output:OutputsOverall: Override skin settingsParanoiaParanoia error correctionPart Of A SetPathPaths must either be absolute or starting with a tilde, which will be expanded to the user's home directory. Drag and drop entries in the list to set the store order in the Music Store.Paths must either be absolute or starting with a tilde.Paths to Music Store databasesPatterns:PausePaymentPerform overlapped readsPerformerPerformer Sort OrderPicture type:PlayPlay CD AudioPlay/PausePlay/Pause songPlay/Stop songPlayback RVAPlayback RVA is currently disabled. Do you want to enable it now?PlaylistPlaylist DelayPlaylist column orderPlaylist: Please enter a new name.Please enter directory name.Please select a Music Store database.Please select a Programable Title Format File.Please select a local path.Please select at least one valid song from playlist.Please select the audio file for this track.Please select the audio files for this record.Please select the directory for exported files.Please select the directory for ripped files.Please select the download directory for this podcast.Please select the root directory.Please select the xml file for this store.Please specify the file to load the image from.Please specify the file to load the playlist from.Please specify the file to save the image to.Please specify the file to save the playlist to.Podcast URL:Podcast support PodcastsPort:Position: %d%%Post Fader (after Volume & Balance)Pre Fader (before Volume & Balance)Predefined transformationsPreviousPrevious songProcessing metadataProcessing:ProducedProfile: BraindeadProfile: InsaneProfile: RadioProfile: StandardProfile: TelephoneProfile: ThumbProfile: XtremeProgrammable title format fileProgramming, GUI engineering: ProgressProgress:Protocol for querying (direct connection only):Proxy host:Proxy settingsPublication RightPublisherPublisher's Official WebsitePublisher/studio logotypePulseAudio Put control buttons at the bottom of playlistQuitRVARVA for Unmeasured Files [dB] :RVA valuesRead CD+GRead CD-DARead CD-RRead CD-RWRead DVD+RRead DVD+RWRead DVD-RRead DVD-RAMRead DVD-ROMRead DVD-RWRead ISRCRead MCNRead Mode 2 Form 1Read Mode 2 Form 2Read multiple sessionsReadingReading fileReally remove "%s" from the Music Store?Really remove '%s' from the Music Store?Really remove store "%s" from the Music Store?ReasonRecordRecord DateRecord LocationRecord nameRecord name (lowercase)Record titlesRecording location/studioRecursive search from the root directory for audio files. The files are processed independently, so only metadata and filename transformation are available.Reference volume [dBFS] :RefreshRegexp matches empty stringRegexp:Regular expressionRelatedRelease TimeRemoveRemove ArtistRemove RecordRemove StoreRemove TrackRemove allRemove artistRemove deadRemove feedRemove file extensionRemove filesRemove item...Remove leading numberRemove non-existing files from storeRemove older items [day]:Remove recordRemove selectedRemove selected songs from playlist (Press right mouse button for menu)Remove storeRemove trackRemoving non-existing filesRenameRename playlistReorder feedsRepeat all songsRepeat current songReplace:ReplayGain Album GainReplayGain Album PeakReplayGain Reference LoudnessReplayGain Track GainReplayGain Track PeakReplayGain tag to use (with fallback to the other): Replaygain_album_gainReplaygain_track_gainReread data for existing tracksReread file metadataRescanResumeRetrieving matches from server...Revision:Right buttonRipRip CDRip CD...Ripping CD tracksRoll to active songRoot path:Running pluginsRussian: SRC Type: STEREOSTOPPINGSample Rate Converter support Sample Rate Converter typeSamplerate:SamplesSamples:SandboxSaveSave all playlistsSave all storesSave and closeSave and restore the playlist on exit/startupSave playlistSave playlist periodically [min]:Save storeScanning filesSearchSearch in:Search the Music StoreSearch the PlaylistSearch...SelectSelect a font...Select allSelect all songs in playlist (Press right mouse button for menu)Select build typeSelect directorySelect filesSelect first and close windowSelect juke-box discSelect noneSelected files:Send to iFP deviceSeparateSet SubtitleSet drive speedSettingsShow AqualungShow RVA valuesShow active track name in boldShow close button in tabShow cover thumbnail for Music Store tracks onlyShow hidden files and directories in file choosersShow song name in the main window's titleShow soundfile size in statusbarShow tags tab first in the file info dialogShow track lengthsShuffle songsSimple view in LADSPA patch builderSingle channelSizeSkin chooserSkin support, look & feel, GUI hacks: Small timers: SoftwareSong in playlist: Song info: Song title: Sort artists bySort records bySound Files (*.wav, *.aiff, *.au, ...)SourceSource file:Start minimizedStatusbar: Steepness [dB/dB] :StereoStopStop adding filesStop adding songsStructure:Subdirectory name length limit:Submit CD to CDDB database...Submit new recordSubmit record to CDDB database...Subscribe to new feedSubtitleSuccessSwedish: SystraySystray support Tag files with metadataTagging TimeTags to add when creating or updating MPEG audio files:Target directory for ripped filesTarget directory:Target file:TestThe email address provided for submission is invalid.The information below is reported by the drive, and may not reflect the actual capabilities of the device.The selected files will be deleted from the filesystem. No recovery will be possible after this operation. Do you want to proceed?The selected song has format unsupported by your player. Do you want to proceed?The specified store has already been added to the list.The store '%s' already exists. Add it on the Settings/Music Store tab.There are unsaved changes to the file metadata.This Aqualung binary is compiled with:This CD does not contain CD-Text information.This button is already assigned.This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.Timeout for socket I/O:TitleTitle FormatTitle Sort OrderTitle appears to be in all lowercase. Do you want to proceed?Title appears to be in all uppercase. Do you want to proceed?Title:Toggle LADSPA patch builderToggle music storeToggle playlistTotalTotal samples:Total: TrackTrack No.Track commentTrack lengthsTrack nameTrack numberTrack titlesTrack:TracksTranslators:Trim leading, tailing and duplicate spacesType:URL:Ukrainian: Unable to open fileUnable to remove %d file.Unable to remove %d files.Undo close tabUnexpected end of string after '?'.United windows minimizationUnknownUnknown AlbumUnknown ArtistUnknown RecordUnknown TrackUnknown conversion type character found after '%%%%'.Unknown conversion type character found after '?'.Unknown discUnknown errorUnlimited retry on failed reads (never skip)UnmeasuredUnmeasured tracks onlyUnrecognizedUntitledUpdate all feedsUpdate feedUpdate file metadataUpdate file metadata...Updating...Use basename only instead of full path if no metadata is available.Use manual RVA value [dB]Use relative paths in store fileUse the local database onlyUser Defined TextUser Defined URLVBR encodingVendorVendor:Verify data integrityVersionVertical mouse wheel:Visible name:Volume level:Volume: %sWarn me if the Window Manager does not support system trayWarningWavPack WavPack (*.wv)When adding new frames, try to set their contents from another tag's equivalent frame.When shuffling, records added in Album mode are played in orderWin32 Sound API Write CD-RWrite CD-RWWrite DVD+RWrite DVD+RWWrite DVD-RWrite DVD-RAMWrite DVD-RWWritingYearYear:You have to provide an email address for CDDB submission.You will need to restart Aqualung for the following changes to take effect:_Abort_Add files..._Browse..._Configure_Download_Uploadartistartistsbestbit doublebit floatbit signedbit unsignedcounting...daydaysdrivedrivesencodingfastfeedfeedsfield:iFP device manager (download mode)iFP device manager (upload mode)iRiver iFP driver support itemitemsnew itemnew itemsrrecordrecordsroot / artist / artist / artist / record / trackroot / artist / artist / record / trackroot / artist / record / trackroot / record / trackrwsecondssndfile (WAV) sndfile (WAV, AIFF, etc.) sndio Audio tag:tracktracksunreachableuse browser window widthProject-Id-Version: aqualung 0.9beta10 Report-Msgid-Bugs-To: POT-Creation-Date: 2010-01-17 16:11+0200 PO-Revision-Date: 2010-01-17 16:13+0300 Last-Translator: Vladimir Smolyar Language-Team: Russian MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Poedit-Language: Russian Максимальное количество попыток: Указанный каталог не доступен для чтения/записи! Здесь вы должны ввести через запятую список доменов, доступ к которым должен осуществляться без использования прокси, установленного выше. Пример: localhost, .localdomain, .my.domain.com Большинство приводов дают Aqualung'у знать, когда вставлен или извлечён CD, уснанавливая флаг 'носитель сменён'. Однако, некоторые приводы не устанавливают этот флаг должным образом, и поэтому вновь вставленный CD может остаться незамеченным Aqualung'ом. В таких случаях должно помочь включение данной функции. Установите скорость привода для проигрывания CD в единицах скорости CD-ROM. Одна единица скорости соответсвует скорости чтения данных 176 кбит/с. Предупреждение: не все приводы принимают эту установку. Низшая скорость обычно означает меньше шума от привода. Однако, при использовании режимов коррекции ошибок Paranoia для повышенной точности, обычно необходимы намного большие скорости, чтобы предотвратить опустошение буфера (и как следствие - слышимых выпадений). Пожалуйста, обратите внимание на то, что эти настройки не влияют на извлечение музыки с CD (Ripping), которое всегда происходит на максимальной доступной скорости и с ручной установкой режимов коррекции ошибок перед каждым сеансом. В выбранной вами Музыкальной библиотеке уже имеется исполнитель и альбом, содержащий треки. Если вы нажмете ОК, эти треки будут удалены. Файлы сами по себе тронуты не будут, но они будут удалены из данной Музыкальной библиотеки. Нажмите Отмена для возврата к изменению исполнителя/альбома или выбору другой Музыкальной библиотеки. Файл, который вы введёте/выберете здесь, установит программу на Lua, используемуюдля форматирования заголовка. Для доп. информации см. справку по Aqualung. Вот быстрый пример того, что вы можете использовать в этом файле: function playlist_title() return m('artist') .. '-' .. m('title') .. ' (' .. m('album') .. ') (' .. i('filename') .. ')' end Строка, которую вы введёте здесь, будет представлена, как командная строка перед обработкой действительных параметров командной строки. То, что вы введёте здесь, будет действовать как значение по умолчанию и может или не может быть отменено из 'настоящей' командной строки. Пример: введите '-o alsa -R' ниже для использования вывода через ALSA в реальном времени по умолчанию. Строка-шаблон, которую вы введёте здесь, будет использоваться для формирования строки заголовка из имён Исполнителя, Записи и Трека. Они обозначены %%%%a, %%%%r и %%%%t соответственно. Строка-шаблон, которую вы введёте сюда, будет использована для формирования имён экспортируемых файлов. Имена Исполнителя, Записи и Трека обозначаются %%%%a, %%%%r и %%%%t. Номер трека и расширение файла, зависящее от формата, обозначаются %%%%n и %%%%x, соответственно. Флаг %%%%i даёт идентификатор, уникальный для данной сеанса экспорта. (%.1f МБ) (%d/%d) (ёмкость = %.1f МБ) Свободное место (%.1f MБ)Выбранные: вых Лвых П% от стандартного отклонения% от стандартного отклонения :%.1f МБ / %.1f МБ%d / %d каталогов%d / %d файлы%d дБ%d из %d песен имеют формат, не поддерживаемый вашиим плеером. Хотите продолжить?%d%% Л%d%% П%ld Гц(без названия)(только аудио)(выберите категорию)(ошибка загрузки изображения)(нет комментария)(нет описания)(нет изображения)(нет)*Информация о файле*Музыкальная библиотека100 пикселов200 пикселов300 пикселов50 пикселовСостояние устройстваЛокальный каталогУдаленный каталогИнформация о песняхПрогресс передачиБольшая цветная рыбаALSA Audio APEПрерватьПрервать текущее обновлениеОтменено...О программеОписаниеДоступДействие:Активная песня в плей-листе: ДобавитьДобавить исполнителяДобавить записьДобавить трекДобавить URLДобавить все элементы в плей-листДобавить все элементы в плей-лист (режим альбома)Добавить каталогДобавить файлыДобавить файлы в плей-лист (Нажмите правой кнопкой мыши, чтобы открыть меню)Добавить элемент...Добавить команду для кнопки мышиДобавить нового исполнителя в эту библиотеку...Добавить нового исполнителя...Добавить новые элементы в плей-листДобавить в плей-лист (режим альбома)Добавить новую запись этого исполнителя...Добавить новую запись...Добавить новый трек в эту запись...Добавить новый трек...Добавить в комментарииДобавить в Музыкальную БиблиотекуДобавить в плей-листДобавить в плей-лист (режим альбома)Добавлять год в комментарии новых записейДобавление файлов в плей-листАльбомПорядок сортировки альбомовИзображение альбомаРежим альбома используется по умолчанию при добавлении целых записейАльбом:ВсеВсе аудио файлыВсе файлыВсе файлы плей-листаВсе трекиВсе словаВсегда показывать строку вкладокВо время подключения к серверу CDDB возникла ошибка.Во время отправки записи на сервер CDDB возникла ошибка.Внешний видПрименить усреднённый уровень RVA для треков из одной записиAqualung скомпилирован с поддержкой системного лотка, но статусная иконка не может быть встроена в область уведомлений. Возможно, ваш рабочий стол не поддерживает системный лоток или неправильно настроен.Aqualung скомпилирован без поддержки дополнений LADSPA. Детали см. в окне О программе и документации.Aqualung скомпилирован без поддержки Преобразователя частоты дискретизации. Детали см. в окне О программе и документации.Плей-лист Aqualung (*.xml)ИсполнительИмя исполнителя в нижнем регистре. Хотите продолжить?Имя исполнителя в верхнем регистре. Хотите продолжить?Имени исполнителяИмени исполнителя (нижний регистр)Именах исполнителейИсполнитель/Альбом уже существуют и непустыПевец/ИсполнительИсполнитель:Запрашивать подтверждение перед удалением элементовПрикреплённая картинкаВставлена картинка без изображения! Пожалуйста, установите изображение или удалите картинку.Аудио CDАудиоданныеАудиофилАвторы:Интервал автопроверки [час]:Автоматически создать треки из этих файлов:Автоматическое обновление запрещено для всех лент во всплывающем меню базы подкастов.Автоматически добавлять CD в плей-листАвтоматически удалять CD из плейлистаАвтоматически перемещаться к активной песнеАвтоматически обновлять лентыДоступные соединенияДоступные расширенияДоступные скиныСреднийУдаров в секундуЗадняя обложкаБаланс: %sГруппа/ОркестрЛоготип группы/исполнителяГруппа/оркестрПоток:Пакетное обновление и кодирование (массовое заполнение тэгов, извлечение из CD, экспорт файлов)Пакетное обновление метаданных файла...БатареяНачалоБиблиографияБольшой таймер: Двоичный объектБитрейт [kbps]:ОбзорПостроить / Обновить библиотеку из файловой системы...Версия сборки: Построить/Обновить библиотекуПостроение библиотеки из файловой системыЗащита от записиКнопкаЦКоррекция ошибок C2CD AudioСкорость привода CD:Поддержка CDDA (Audio CD) CDDBCDDB (недоступно)Поиск в CDDBЗапрос CDDBЗапрос CDDB для этого CD...Запрос CDDB для этой записи...Сервер CDDB:Поддержка CDDB CDDBP (порт 888)Вычислить уровень RVAРассчитать громкостьВычислить громкость (рекурсивно)Расчет уровня громкостиНевозможно записать в выбранный каталог. Выберите, пожалуйста, другой каталог.Преобразование в заглавные буквыПреобразовать в заглавные:С учётом регистраНомер каталогаКатегорияКатегория.ИзменитьИзменить балансИзменить текущую песнюИзменить позицию песниИзменить громкостьЧисло каналов:Каналы:Закрыть соединенияОчистить списокЩёлкните здесь, чтобы установить кнопку мышиЗакрытьЗакрыть другие вкладкиЗакрыть вкладкуЗакрытие лотокЗакрыть окно после завершенияЗакрыть окно по окончании передачиСвернуть все элементыЦветаКолонкаОбъединить кнопки паузы и воспроизведенияКомандаКомментарийКомментарияхКомментарии:Коммерческая информацияКомпозиторСжатые модули (*.bz2)Сжатые модули (*.gz)Сжатые модули (*.gz, *.bz2)Уровень сжатия:Сжатие: Очень сильноеСжатие: БыстроеСжатие: СильноеСжатие: НеимоверноеСжатие: НормальноеДирижёрПодключение через HTTP-проксиПодключение к серверу CDDB...Лимит времени ожидания соединения [сек]:Контактная информацияТип содержимогоОшибка преобразования в поле %s: '%s' не соответсвует формату '%s'!Преобразование в целевую кодировку не удалосьПреобразовывать подчеркивание в пробелКопироватьАвторское правоАвторское право/юридическая информацияДизайн, проектирование и программирование: Исправить существующую записьНевозможно загрузить изображение из: %sОбложкаСоздать новый каталогСоздать каталогСоздать пустую библиотекуСоздать пустую библиотеку...Создать подкаталоги для альбомовСоздать подкаталоги для исполнителейТекущий файл:Вырезать выбранноеDSPДатаДебютный альбомПоддержка декодирования:Ширина обложки по умолчанию:Удалить загруженные элементы из файловой системыОписаниеОписание:ЦельОпределение смены носителяУстройство занято. (Aqualung не смог установить свой интерфейс.)Устройство не отвечает. Попробуйте пошевелить рукояткой.Путь к устройству:Прямое подключение к ИнтернетуКаталог '%s' будет удалён вместе со всем содержимым. Хотите продолжить?В соответствии с каталогамиИмени каталогаИмени каталога (в нижнем регистре)Структура каталогаОтключить все расширенияОтключить рельеф управляющих кнопокЗапрет ручного извлеченияОтключить поддержку скиновДискИнформация о дискеИнформация о диске...Отменить измененияНе закрыватьНе выходитьНе увеличивать изображения меньшей шириныНе перекодировать файлы, удовлетворяющие маске:Не перекодировать файлы, которые уже в нужном форматеНичего не делатьХотите сохранить библиотеку "%s" перед удалением из Музыкальной Библиотеки?Хотите сохранить библиотеку перед удалением?Не показывать миниатюру обложки в главном окнеГотовоКаталог загрузки:Загрузка %d/%d (%d%%) ...Перетащите содержимое в списке, чтобы установить порядок лент в Музыкальной Библиотеке.Перетащите содержимое в списке ниже, чтобы установить порядок колонок в плейлисте.Информация о дискеИнформация о диске...Пренебрегать случайными отклонениями, основываясь наДва каналаПродолжительность:Во время исполненияВо время записиEAN/UPCРедактировать исполнителяРедактировать записьРедактировать библиотекуРедактировать трекРедактировать исполнителя...Редактировать лентуРедактировать свойства лентыРедактировать элемент...Редактировать запись...Редактировать библиотеку...Редактировать трек...Извлечение лоткаАдрес электронной почты для подписки:Встроить плейлист в основное окноВыделение:Выделение: нетВыделение: зарезервированоРазрешить значки узлов дерева в Музыкальной БиблиотекеВключить все расширенияВключить Автоматическое Уравнивание Громкости (RVA)Чередующаяся окраска строк в спискеВключить строку состоянияРазрешить строку состояния в Музыкальной библиотекеВключить строку состояния в плей-листеРазрешить системный лотокВключить панель инструментовРазрешить панель инструментов в Музыкальной библиотекеВключить подсказкиРазрешить значки узлов дереваРазрешёнЗакодированоВремя кодированияПоддержка кодирования:Добавить в плей-листОшибкаОшибка преобразования поля %s в год: '%s' не является целым числом!Ошибка в строке форматаОшибка в строке формата заголовкаТолько точные совпаденияИсключить файлы, удовлетворяющие маскеРазвернуть библиотеки при запускеОжидалось '}' после '{', а найден конец строки.Экспорт всех элементов...Экспортировать исполнителя...Экспорт файловЭкспорт элемента...Экспорт новых элементов...Экспортировать запись...Экспорт библиотеки...Экспорт трека...Экспорт файловФайлы расширенного форматирования заголовка (*.lua)Расширенные данные:Картинки FLACНевозможно установить метаданные для следующих файлов:Невозможно записать метаданные в файл. Причина: %sФайлФайл "%s" не существует или у вас нет прав записи в него. Проверьте, не отмонтирован ли раздел, на котором расположен файл библиотеки.Файл '%s' будет удален. Хотите продолжить?Владелец файлаТип файлаФормат файла:Значок файла (32x32 PNG)Значок файла (другое)Информация о файлеИнформация о файле...Файл не доступен для записиИмя файла:Файл:Имя файлаШаблон имени файла:Имя файла:Выбранные для удаления файлыФайловая системаФильтрТолько первое словоСледует по структуре каталогов для определения исполнителей и записей. Файлы добавляются на основе записей. ШрифтыПринудительно перечитывать таблицу файлов при каждом сканировании дискаПринудительно:Преобразовать остальные буквы в нижний регистрФорматФормат:Free Lossless Audio Codec (*.flac)Free Lossless Audio Codec (FLAC) Свободное местоФранцузский: Передняя обложкаОбщиеОбщие метаданные потокаЖанрЖанр:Немецкий: Графика:HTTP (порт 80)Жёсткий сброс устройстваПомощьСкрыть AqualungСпрятать панель комментарияСпрятать панель комментария в Музыкальной БиблиотекеДомашняя страница:Горизонтальное колесо мыши:Венгерский: IDID3v1ID3v2ISBNISRCОписание станцииЖанр станцииНазвание станцииБездействиеИллюстрацияподразумеваемая командная строкаИмпортировать тэг комментарияИмпортировать тэг Replaygain как ручную настройку RVAИмпортировать как исполнителяИмпортировать как уровень RVAИмпортировать как записьИмпортировать как ключ сортировкиИмпортировать как заголовокИмпортировать как № трекаИмпортировать как годВ любом случаеВключить только файлы, удовлетворяющие маскеНезависимыйСодержаниеНачальный ключВходыИнструментыИнструменты:Внутренняя ошибкаИнтернетНазвание интернет-радиостанцииВладелец интернет-радиостанцииИнтерпретация/РемиксВведениеНеверное значение поля 'Жанр'Неверное значение поля 'Номер трека'Инвертировать текущее состояниеИнвертировать выделениеУчастникиСудя по всему, год указан неверно. Хотите продолжить?Итальянский: JACK Audio Server Настройка порта JACKПотеряно соединение JACKJACK или выключился, или отсоединил Aqualung из-за того, что он был недостаточно быстр. Всё, что вы можете сейчас сделать, это перезапустить и JACK, и AqualungНастройка порта JACKЯпонский: объедидённое стереоРазмещать главное окно всегда сверхуКлюч: Сборщик патчей LADSPAОбработка дополнения LADSPAПоддержка расширений LADSPA LAME (MP3) LAVC (AC3, AAC, WavPack, WMA, etc.) Аудио/видео файлы LAVCКод лэйблаЯзыкСлой IСлой IIСлой IIIВедущий певец/исполнительВкладышЛевая и правая кнопки мыши зарезервированы.Левая кнопкаДлинаДлина:ЛицензияПределыЛинейном пороге [дБ]Линейный порог [дБ] :Среда прослушивания:ГостиннаяЗагрузить плей-листЗагрузить плей-лист в новую вкладкуЗагрузить настройки из файла Музыкальной библиотекиЛокальный каталог CDDB:РасположениеМестоположение и имя файлаЛоготип, иконки: Поддержка зацикленного воспроизведения Диапазон повтора: %d-%d%%Диапазон повтора: %d-%d%% [%s - %s]Поддержка Lua (программируемое форматирование заголовка) Поэт/автор текстаПоэт/автор текстаТип MIME: %sMOD Audio (MOD, S3M, XM, IT, etc.) МОНОПлей-лист MP3 (*.m3u)MPEG Audio (*.mp3, *.mpa, *.mpega, ...)MPEG Audio (MPEG 1-2.5 Layer I-III) Метаданные MPEG-потокаГлавное окноСовпадения:Максимальное число элементов:Максимальное количество попыток:Максимальное используемое пространство [Мб]:НосительОшибка выделения памятиМетаданныеРедактор метаданных (диалог информации о файле)Средняя кнопкаРазноеРежим:Модель:Информация о модулеМодули (*.xm, *.mod, *.it, *.s3m, ...)Monkey's Audio Codec Monkey's Audio Codec (*.ape)НастроениеПакетная запись (Mount Rainier)Кнопка мышиКнопки мышиКолесо мышиКадр из кино/видеофильмаМультимедиа плей-лист (*.pls)Musepack Musepack (*.mpc)Уравнивание громкости MusepackМузыкальная библиотекаФайлы музыкальной библиотеки (*.xml)Музыкальная библиотека: Благодарности музыкантовПриглушить звукNULLИмяИмя для сортировки:Преобразование имениИмя:Новая вкладкаСледующийСледующая песняНет дискаСовпадений не найдено.Нет поддержки метаданных для этого форматаНет выводаНе использовать прокси для:Подходящего устройства iRiver iFP не найдено. Возможно, оно отсоединено или выключено.№Шумная мастерскаяНетФормат ни одной из выбранных вами песен не поддерживается вашим плеером. Хотите продолжить?Примечание: существующие тэги будут обновлены даже если они не выбраны здесь.OSS Audio ОфисОфициальная веб-страница исполнителяОфициальная веб-страница аудиофайлаОфициальная веб-страница источника аудиоОфициальная веб-страница радиостанцииOgg Speex Ogg Speex (*.spx)Ogg Vorbis Ogg Vorbis (*.ogg)Комментарии Ogg XiphОдна или более библиотек в Музыкальной Библиотеке изменена. Хотите сохранить их перед выходом?Одна из песен имеет формат, не поддерживаемый вашиим плеером. Хотите продолжить?Только если измеренСовместимость с OpenBSD, трюки с метаданными: Дополнительные возможности:ОрганизацияОригинальное название альбомаОригинальное имя исполнителяОригинальное имя файлаОригинальное имя поэтаВремя выпуска оригиналаДругоеВыходПоддержка драйверов вывода:Вывод:ВыходыВсего: Сбросить настройки скинаParanoiaКорректирование ошибок ParanoiaЧасть набораПутьПути должны быть или абсолютными, или начинаться с тильды, которая будет преобразована в домашний каталог пользователя. Перетащите содержимое в списке, чтобы установить порядок хранения в Музыкальной Библиотеке.Пути должны быть абсолютными или начинаться с тильды.Пути к базам данных музыкальной библиотекиПаттернов:ПаузаОплатаПроизводить чтения с перекрытиемИсполнительПорядок сортировки ИсполнителейТип изображения:ИгратьПроигрывание CD AudioВоспроизведение/ПаузаИграть/Остановить песнюИграть/Остановить песнюАУГ (RVA)АУГ (RVA) в данный момент отключено. Хотите включить его сейчас?Плей-листЗадержка плей-листаПорядок колонок в плей-листеПлей-лист: Введите, пожалуйста, новое имя.Введите, пожалуйста, название каталога.Выберите, пожалуйста, базу данных музыкальной библиотеки.Выберите, пожалуйста файл программируемого форматирования заголовка.Выберите, пожалуйста, локальный путь.Выберите, пожалуйста, хотя бы одну допустимую песню из плей-листа.Пожалуйста, выберите аудиофайл для этого трека.Пожалуйста, выберите аудиофайлы для этой записи.Выберите, пожалуйста, каталог для экспортированных файлов.Выберите, пожалуйста, каталог для извлеченных файлов.Пожалуйста, выберите каталог загрузки для этого подкаста.Выберите, пожалуйста, корневой каталог.Выберите, пожалуйста, xml-файл для этой библиотеки.Укажите, пожалуйста, файл, из которого необходимо загрузить изображение.Укажите, пожалуйста, файл, из которого необходимо загрузить плей-лист.Укажите, пожалуйста, файл для сохранения изображения.Укажите, пожалуйста, файл для сохранения плей-листа.URL подкаста:Поддержка подкастов ПодкастыПорт:Позиция: %d%%Постусилитель (после громкости и баланса)Предусилитель (до громкости и баланса)Предустановленные преобразованияПредыдущийПредыдущая песняОбработка метаданныхПрогресс:ПродюсерПрофиль: Без башниПрофиль: СумасшедшийПрофиль: РадиоПрофиль: СтандартПрофиль: ТелефонПрофиль: ЭскизПрофиль: Экстремальныйфайл программируемого форматирования заголовкаПрограммирование, графический интерфейс: ПрогрессПрогресс:Протокол для запросов (только прямое соединение):Адрес прокси:Настройки проксиПрава на публикациюИздательОфициальная веб-страница издателяЛоготип издателя/студииPulseAudio Разместить кнопки управления внизу плей-листаВыходАУГ (RVA)Уровень RVA для неизмеренных файлов [дБ] :Значения RVAЧтение CD+GЧтение CD-DAЧтение CD-RЧтение CD-RWЧтение DVD+RЧтение DVD+RWЧтение DVD-RЧтение DVD-RAMЧтение DVD-ROMЧтение DVD-RWСчитывание ISRC (Международного стандартного номера записи)Считывать MCNЧтение Mode 2 Form 1Чтение Mode 2 Form 2Чтение многосессионных дисковЧтениеЧтение файлаДействительно удалить "%s" из музыкальной библиотеки?Действительно удалить '%s' из Музыкальной Библиотеки?Действительно удалить библиотеку "%s" из Музыкальной библиотеки?ПричинаЗаписьДата записиМесто записиНазвание записиНазвание записи (нижний регистр)Названиях записейМесто записи/студияРекурсивный поиск аудио файлов, начиная с корневого каталога. Файлы обрабатываются независимо, так что доступны только метаданные и преобразование имён файлов.Опорный уровень [дБ полная шкала] :ОбновитьРегулярное выражение совпадает с пустой строкойРегВыр:Регулярное выражениеСвязанное содержимоеДата релизаУдалитьУдалить исполнителяУдалить записьУдалить библиотекуУдалить трекУдалить всеУдалить исполнителяУдалить мёртвыеУдалить лентуУбирать расширение файлаУдалить файлыУдалить элемент...Убирать число в началеУдалить несуществующие файлы из библиотекиУдалить устаревшие элементы [день]:Удалить записьУдалить выделенныеУдалить выделенные песни из плей-листа (Нажмите правой кнопкой мыши, чтобы открыть меню)Удалить библиотекуУдалить трекУдаление несуществующих файловПереименоватьПереименовать плей-листИзменить порядок лентПовторять все песниПовторять текущую песнюЗамена:Коэффициент усиления альбома для выравнивания громкости (ReplayGain)Пик альбома для выравнивания громкости (ReplayGain)Опорная громкость Выравнивания громкости (ReplayGain)Коэффициент усиления трека для выравнивания громкости (ReplayGain)Пик трека для выравнивания громкости (ReplayGain)Используемый тэг ReplayGain (с отходом на другой):Replaygain_track_gainReplaygain_track_gainПеречитать данные для имеющихся трековПеречитать метаданные файлаПеречитатьВозобновитьПолучение результатов с сервера...Пересмотр:Правая кнопкаИзвлечь музыкуИзвлечь музыку из CDИзвлечение музыки с CD...Считывание CD-трековСкатиться к активной песнеКорневой путь:Запущенные расширенияРусский: Тип SRC:СТЕРЕООСТАНОВКАПоддержка конвертера частоты дискретизации Тип преобразователя частоты дискретизацииЧастота дискретизации:ФрагментыФрагментов:ПесочницаСохранитьСохранить все плей-листыСохранить все библиотекиСохранить и закрытьСохранять и восстанавливать плей-лист при закрытии/запускеСохранить плей-листПериодически сохранять плей-лист [мин.]:Сохранить библиотекуСканирование файловПоискИскать в:Поиск в музыкальной библиотекеПоиск в плей-листеПоиск...ВыбратьВыбрать шрифт...Выбрать всеВыбрать все песни плей-листа (Нажмите правой кнопкой мыши, чтобы открыть меню)Выберите тип сборкиВыбрать каталогВыбрать файлыВыбрать первый и закрыть окноВыбор диска в CD-чейнджереНичего не выбиратьВыбранные файлы:Отправить на устройство iFPПо отдельностиУстановить подзаголовокВыбор скорости приводаНастройкиПоказать AqualungПоказать значения RVAПоказывать название активного трека жирнымПоказывать кнопку закрытия в закладкеПоказывать миниатюру обложки только для треков из Музыкальной библиотекиПоказывать скрытые файлы и каталоги в диалогах выбора файлаПоказывать название песни в заголовке главного окнаОтображать размер файла в строке состоянияПоказывать вкладку тэгов первой в окне информации о файлеПоказывать длину трековПеремешать песниПростой вид в сборщике патчей LADSPAОдин каналРазмерВыбор скинаПоддержка скинов, внешний вид: Маленькие таймеры: ПрограммаПесня в плей-листе: Информация о песне: Название песни: Сортировать исполнителей поСортировать записи поЗвуковые файлы (*.wav, *.aiff, *.au, ...)ИсточникИсходный файл:Запускать минимизированнымСтрока состояния: Крутизна [dB/dB] :СтереоСтопОстановить добавление файловОстановить добавление песенСтруктура:Максимальная длина имени подкаталога:Отправить данные об этом CD в базу данных CDDB...Отправить новую записьОтправить запись в базу данных CDDB...Подписаться на новую лентуПодзаголовокУспешноШведский: Системный лотокПоддержка системного лотка Ввести метаданные в файлыВремя внесения тэгаТэги, добавляемые при создании или изменении аудиофайлов MPEG:Каталог назначения для извлеченных файловКаталог назначения:Файл назначения:ТестАдрес электронной почты, предоставленный для подписки, недействителен.Информация ниже получена из устройства, и может не отображать действительных возможностей устройства.Выбранные файлы будут удалены из файловой системы. После этого восстановить их будет невозможно. Хотите продолжить?Выбранная песня имеет формат, не поддерживаемый вашиим плеером. Хотите продолжить?Указанная библиотека уже добавлена в список.Библиотека '%s' уже существует. Добавьте её на вкладке Настройки/Музыкальная Библиотека.Есть несохранённые изменения в метаданных файла.Этот исполнимый файл Aqualung скомпилирован с:Этот CD не содержит информации CD-Text.Эта клавиша уже назначена.Эта программа является свободным программным обеспечением; вы можете распространять её и/или изменять по условиям Универсальной общественной лицензии GNU в виде, опубликованном Фондом свободного программного обеспечения; как версии 2, так и (по вашему усмотрению) любой более поздней версии. Эта программа распространяется в надежде, что она будет полезной, но БЕЗ КАКОЙ-ЛИБО ГАРАНТИИ; даже без подразумеваемой гарантии ТОВАРНОЙ ПРИГОДНОСТИ или СООТВЕТСТВИЯ КОНКРЕТНОМУ НАЗНАЧЕНИЮ. Для более детальной информации см. Универсальную общественную лицензию GNU. Вы должны были получить копию Универсальной общественной лицензии GNU вместе с этой программой; если нет, то напишите В Фонд свободного программного обеспечения: Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.Время ожидания ввода/вывода сокета:ЗаголовокФормат заголовкаПорядок сортировки названийНазвание в нижнем регистре. Хотите продолжить?Название в верхнем регистре. Хотите продолжить?Название:Вкл./Выкл. сборку патчей LADSPAВкл./Выкл. Музыкальную БиблиотекуВкл./Выкл. плейлистВсегоВсего сэмплов:Всего:ТрекНомер трекаКомментарий к трекуДлины трековИмя трекаНомер трекаНазвания трековТрек:ТрекиПереводчики:Обрезать пробелы в начале, конце и повторяющиесяТип:URL:Украинский: Невозможно открыть файлНевозможно удалить %d файл.Невозможно удалить %d файловОтменить закрытие вкладкиНеожиданный конец строки после '?'.Объединённая минимизация оконНеизвестныйНеизвестный альбомНеизвестный исполнительНеизвестная записьНеизвестный трекПосле '%%%%' обнаружен символ неизвестного типа.После '?' обнаружен символ неизвестного типа.Неизвестный дискНеизвестная ошибкаНеограниченное число попыток при ошибках чтения (никогда не пропускать)НеизмеренныйТолько неизмеренные трекиНе распознаноБез названияОбновить все лентыОбновить лентуОбновить метаданные файлаОбновить метаданные файла...Обновление...Использовать только основное имя вместо полного пути, если не доступны метаданные.Использовать свой уровень RVA [дБ]Использовать относительные пути в файле библиотекиИспользовать только локальную базу данныхПользовательский текстПользовательский URLКодирование с переменным потокомПроизводительПроизводитель:Проверить целостность данныхВерсияВертикальное колесо мыши:Выводимое имя:Уровень громкости:Громкость: %sПредупредить меня, если оконный менеджер не поддерживает системный лотокВниманиеWavPack WavPack (*.wv)При добавлении новых полей пытаться установить их содержимое из эквивалентных полей другого тэга.В режиме перемешивания записи, добавленные в режиме альбома, проигрываются по порядкуWin32 Sound API Запись CD-RЗапись CD-RWЗапись DVD+RЗапись DVD+RWЗапись DVD-RЗапись DVD-RAMЗапись DVD-RWЗаписьГодГод:Вы должны указать адрес email для отправки CDDB.Вам придётся перезапустить Aqualung, чтобы вступили в силу следующие изменения:_Прервать_Добавить файлы..._Обзор..._Настройки_Загрузить_Выгрузитьисполнительисполнителилучшебит двойнойбит с плавающей точкойбит знаковыйбит беззнаковыйподсчет...деньднидискдискикодированиебыстрееленталентыполе:Менеджер устройства iFP (режим загрузки)Менеджер устройства iFP (режим выгрузки)Поддержка драйвера iRiver iFP элементэлементыновый элементновые элементытолько чтениезаписьзаписикорень / исполнитель / исполнитель / исполнитель / запись / треккорень / исполнитель / исполнитель / запись / треккорень / исполнитель / запись / треккорень / запись / трекчтение/записьсекундsndfile (WAV) sndfile (WAV, AIFF, etc.) sndio Audio тег:дорожкадорожкиНедосягаемиспользовать ширину окна браузераaqualung-0.9beta11/src/po/sv.mo0000644000175000001440000015646611331334313013321 00000000000000$<?\2XCYCuCFD2aEF[MG HHHH HHHII5IGI [IiIOoIIII I IIJ J#J 4J?J FJ QJ ^J iJ tJ JJJJJJJ KKK%K :KEKKKRKZKtK xK K KKK&K K K9K 3L?L_LqL&L LLLMM&M9MIM'fMMM M4MMMM NN &N 1N;NASNAN N/NOhOpLPPP>P>Q \QhQ Q(QQQ(QQ R R R(R$1RRVR!R&RR S#S5SESMS QS \ShSwSS SSSS S S SS T'T8THT[TzT|TTTTTT T TT U +U 8UFU WUeUvUUDUU V VV+V 4V>VEV TV^V pV{VV V VV#VVVWW&W.W 7WAWXWaW|W WWWWWXX .X8XOXlXtXX XX(XXX Y$Y;YLY_Y uY!YY YY YYY+ Z 8Z DZQZ=eZ2Z Z!ZQ[W[f[[[[[[ [ [[ [ \(\(A\8j\@\.\-]A]F]Z]Kw]Q] ^ ^ .^ ;^E^X^i^ q^ }^ ^ ^^ ^^ ^^ ^ ^_ _'_G_Z_n_______` ` `)`;`L`R`i```` ````aa(a#8a\a ka/ya,aa3a b b $b1bGb Yb cbpb bbbb bb bbbkbfc lccc"c!c c ccdd d d d/d 4dBd!Td vd dddddd dd#dd d ee+e?e Ne$Ze ee e eeeeeef,fLfA\f fffffpg gggg g$g hh!h)h 2hzFzOzTzgzwz-z z!z zzz {{'{ ;{E{L{ ]{@h{{ {{{ {||)|2|B| K|Y|i||0|)| |} 0}>}M} R}&_}}}} } }}}&}~ ~ %~1~8~=~O~ a~l~~!~~~~~ 7!Jl ~5j,Q7F:/&-؁ ==(/BRXgo u  Dž ΅ۅ  ; JXg v  ņچ  4AHPf n | :Ї؇?0 A L X d q } 9K1 8 F Q \fnu} "ĉ #(. 7ACJ0R'ʊ "'-o4ČM|Fʎtِ NYbx ْ  Ugnu | $̓ޓ '7GWfzޔ  )5 8 FP hs%2ܕ"E3y,$Ӗ1(*S)jƗ#-!Km s4} ؘ͘ ?CY7ޙqƚz8ΛK՛L! ny #Ŝ՜.ݜ !* 3*@fk/ҝ-!0Rm  ̞ڞ '/ 6 BO^s-| %П #>C \ gs ˠ ܠF( o }  áҡۡ   #,)Pz# ¢ ̢ آ  &"Beyϣ &(O U_:~"Ҥ  #<X"x  ̥ݥ& $ 0=AQ-ѦN ?Kiy˧Ч  &!*H/sE-+CH[[t[Щ,>S boΪݪ!%8J`rz$ܫ' "4Wt% ŬϬ ج  '! Ijӭ"! D R>^8֮2ڮ  )=M\n  ϯٯnb5k"!Ӱ !'.6>MTc-x DẔѱ ٱ>=Rdx,ز   ! -9B `'-? ;H[q@ V'c ˵$׵  )1:A P[m/жֶ42L f#s'$ڷ#6Zo*x'  - JTetɹϹ׹ ޹ # 9FQX_ƺb&  ػ# ( :FYanMм2Q erƽ6(? hr x Jľ 0 MX!s(3 3)G+q..;7+T26.2L^x   %5D5d ( 24go s  *B I6T6@  1: U`x    += Q_.q J( :Hhq#   % /<L`t)  (.DY7j *28 NA[ !  !*D Sar4%$+ ?MV ^:k  $= DN]dk #&")B [Hh" @\+[6oT0),/VH EF'nu  #27 <H\u '= V d!  K]enN}  '4<@GD^  "*29B HSW] drz %'    & 1>D/K&{ $*0GLV() s<'Z/ n%bQ+|eRuy$a;k6r6O0/PYbX}WF_H #24V8$Ki7Sg0}N*#`shtOR"z18>=G}X9`z2DoK9. dfT &H|k?Jt _fq{3 N\M>C'nvS'YDqpV) acz3CU pB85 B@~!1oQWxITjtm:MG-&EQ9<!vHbnjN^ +"!WEKM"g;w!c <L."\\  ,luU[J+x?Ayv]YL>$r=k?J^#01a%&:Z]7 , *F2=(ii X C3#(.Ox~6~`,Rm-P wTpZl_h %] Djy5{o m^ f{4d[Bg4uI;qs/ FeA*lU-P[5I7E$:)e@wc|@rAdhS Maximum number of retries: Here you should enter a comma-separated list of domains that should be accessed without using the proxy set above. Example: localhost, .localdomain, .my.domain.com The Music Store you selected has a matching Artist and Album, already containing some tracks. If you press OK, these tracks will be removed. The files themselves will be left intact, but they will be removed from the destination Music Store. Press Cancel to get back to change the Artist/Album or the destination Music Store. The file you enter/choose here will set the Lua program to use to format the title. See the Aqualung manual for details. Here is a quick example of what you can use in the file: function playlist_title() return m('artist') .. '-' .. m('title') .. ' (' .. m('album') .. ') (' .. i('filename') .. ')' end The template string you enter here will be used to construct a single title line from an Artist, a Record and a Track name. These are denoted by %%%%a, %%%%r and %%%%t, respectively. The template string you enter here will be used to construct the filename of the exported files. The Artist, Record and Track names are denoted by %%%%a, %%%%r and %%%%t. The track number and format-dependent file extension are denoted by %%%%n and %%%%x, respectively. The flag %%%%i gives an identifier which is unique within an export session. (%.1f MB) (%d/%d) (capacity = %.1f MB) Free space (%.1f MB) Selected: out L out R% of standard deviation% of standard deviation :%.1f MB / %.1f MB%d / %d directories%d / %d files%d dB%d of %d songs have format unsupported by your player. Do you want to proceed?%d%% L%d%% R%ld Hz(Untitled)(audio only)(choose a category)(error loading image)(no comment)(no description)(no image)(none)*File info*Music Store100 pixels200 pixels300 pixels50 pixelsDevice statusLocal directoryRemote directorySongs infoTransfer progressA large, coloured fishALSA Audio APEAbortAbort ongoing updateAborted...AboutAccessAction:Active song in playlist: AddAdd ArtistAdd RecordAdd TrackAdd URLAdd all items to playlistAdd all items to playlist (Album mode)Add directoryAdd filesAdd files to playlist (Press right mouse button for menu)Add item...Add new artist to this store...Add new artist...Add new items to playlistAdd new items to playlist (Album mode)Add new record to this artist...Add new record...Add new track to this record...Add new track...Add to CommentsAdd to Music StoreAdd to playlistAdd to playlist (Album mode)Add year to the comments of new recordsAdding files to PlaylistAlbumAlbum imageAlbum mode is the default when adding entire recordsAlbum:AllAll Audio FilesAll FilesAll Playlist FilesAll tracksAll wordsAlways show the tab barAn error occurred while attempting to connect to the CDDB server.An error occurred while submitting the record to the CDDB server.AppearanceApply averaged RVA to tracks of the same recordAqualung is compiled with system tray support, but the status icon could not be embedded in the notification area. Your desktop may not have support for a system tray, or it has not been configured correctly.Aqualung is compiled without LADSPA plugin support. See the About box and the documentation for details.Aqualung is compiled without Sample Rate Converter support. See the About box and the documentation for details.Aqualung playlist (*.xml)ArtistArtist appears to be in all lowercase. Do you want to proceed?Artist appears to be in all uppercase. Do you want to proceed?Artist nameArtist name (lowercase)Artist namesArtist/Album already existing, not emptyArtist/performerArtist:Ask for confirmation when removing itemsAttached PictureAudio CDAudio dataAudiophileAuthors:Auto-create tracks from these files:Automatic update has been disabled for all feeds in the Podcasts store popup menu.Automatically add CDs to PlaylistAutomatically remove CDs from PlaylistAutomatically update feedsAvailable connectionsAvailable pluginsAvailable skinsAverageBPMBack coverBalance: %sBand/OrchestraBand/artist logotypeBand/orchestraBandwidth:Batch-update file metadata...BatteryBeginBibliographyBig timer: Binary ObjectBitrate [kbps]:BrowseBuild / Update store from filesystem...Build version: Build/Update storeBuilding store from filesystemCC2 Error CorrectionCD AudioCD drive speed:CDDA (Audio CD) support CDDBCDDB (not available)CDDB lookupCDDB queryCDDB query for this CD...CDDB query for this record...CDDB server:CDDB support CDDBP (port 888)Calculate RVACalculate volumeCalculate volume (recursive)Calculating volume levelCannot write to selected directory. Please select another directory.CapitalizationCapitalize: Case sensitiveCatalog NumberCategoryCategory:ChangeChannel count:Channels:Clear connectionsClear listCloseClose other tabsClose tabClose trayClose window when completeClose window when transfer completeCollapse all itemsColorsColumnCombine play and pause buttonsCommentCommentsComments:Commercial InformationComposerCompressed modules (*.bz2)Compressed modules (*.gz)Compressed modules (*.gz, *.bz2)Compression level:Compression: Extra HighCompression: FastCompression: HighCompression: InsaneCompression: NormalConductorConnect via HTTP proxyConnecting to CDDB server...ContactConvert underscore to spaceCopyCopyrightCopyright/Legal InformationCore design, engineering & programming: Correct existing recordCould not load image from: %sCover artCreate a new directoryCreate directoryCreate empty storeCreate empty store...Create subdirectories for albumsCreate subdirectories for artistsCurrent file: Cut selectedDateDebut AlbumDecoding support:Default cover width:Delete downloaded items from the filesystemDescriptionDescription:Detect media changeDevice is busy. (Aqualung was unable to claim its interface.)Device is not responding. Try jiggling the handle.Device path:Direct connection to the InternetDirectory '%s' will be removed with its entire contents. Do you want to proceed?Directory nameDirectory name (lowercase)Directory structureDisable all pluginsDisable manual ejectDisable skin supportDiscDisc infoDisc info...Discard changesDo not closeDo not exitDo not magnify images with smaller widthDo not reencode files matching wildcard:Do not reencode files already being in the target formatDo you want to save store "%s" before removing from Music Store?Do you want to save the store before removing?Don't show cover thumbnail in the main windowDoneDownload directory:Downloading %d/%d (%d%%) ...Drag and drop entries in the list to set the feed order in the Music Store.Drag and drop entries in the list below to set the column order in the Playlist.Drive infoDrive info...Dual channelDuration:During performanceDuring recordingEAN/UPCEdit ArtistEdit RecordEdit StoreEdit TrackEdit artist...Edit feedEdit feed settingsEdit item...Edit record...Edit store...Edit track...EjectEmail address for submission:Embed playlist into main windowEnable all pluginsEnable playback RVAEnable statusbarEnable statusbar in Music StoreEnable statusbar in playlistEnable systrayEnable toolbarEnable toolbar in Music StoreEnable tooltipsEnabledEncoded byEncoding TimeEncoding support:Enqueue playlistErrorError in format stringExclude files matching wildcardExpand Stores on startupExport all items...Export artist...Export filesExport item...Export new items...Export record...Export store...Export track...Exporting filesExtended Title Format Files (*.lua)Extended data:FLAC PicturesFailed to set metadata for the following files:Failed to write metadata to file. Reason: %sFileFile '%s' will be removed. Do you want to proceed?File OwnerFile TypeFile format:File icon (32x32 PNG)File icon (other)File infoFile info...File is not writableFile name: File:FilenameFilename template:Filename:Files selected for removalFilesystemFilterFirst word onlyFollows the directory structure to identify the artists and records. The files are added on a record basis.FontsForce other letters to lowercaseFormatFormat:Free Lossless Audio Codec (*.flac)Free Lossless Audio Codec (FLAC) Free spaceFront coverGeneralGenreGenre:German: Graphics:HTTP (port 80)HelpHide AqualungHide comment paneHide the Music Store comment paneHomepage:Hungarian: ID3v1ID3v2ISBNISRCIdleIllustrationImport Comment tagImport Replaygain tag as manual RVAImport as ArtistImport as RVAImport as RecordImport as TitleImport as Track No.Import as YearIn any caseInclude only files matching wildcardIndependentInputsInstrumentsInstruments:Internal errorInternetInternet Radio Station NameInternet Radio Station OwnerInterpreted/RemixedInvalid 'Genre' field valueInvalid 'Track no.' field valueInvolved PeopleIt is very likely that the year is wrong. Do you want to proceed?Italian: JACK Audio Server JACK Port SetupJACK connection lostJACK has either been shutdown or it disconnected Aqualung because it was not fast enough. All you can do now is restart both JACK and Aqualung.JACK port setupJoint stereoKeep main window always on topLADSPA plugin processingLADSPA plugin support LAME (MP3) LAVC (AC3, AAC, WavPack, WMA, etc.) Label CodeLanguageLayer ILayer IILayer IIILengthLength:LicenseLimitsLiving roomLoad playlistLoad playlist in new tabLoad settings from Music Store fileLocal CDDB directory:LocationLocation and filenameLogo, icons: Lua (programmable title formatting) support Lyricist/Text WriterLyricist/text writerMIME type: %sMOD Audio (MOD, S3M, XM, IT, etc.) MONOMP3 Playlist (*.m3u)MPEG Audio (*.mp3, *.mpa, *.mpega, ...)MPEG Audio (MPEG 1-2.5 Layer I-III) Maximum number of items:Maximum number of retries:Maximum space to use [MB]:Memory allocation errorMetadataMetadata editor (File info dialog)MiscellaneousMode:Model:Modules (*.xm, *.mod, *.it, *.s3m, ...)Monkey's Audio Codec Monkey's Audio Codec (*.ape)MoodMount RainierMultimedia Playlist (*.pls)Musepack Musepack (*.mpc)Music StoreMusic Store Files (*.xml)Music Store: MuteNULLNameName to sort by:Name:New tabNextNext songNo discNo matching record found.No metadata support for this formatNo outputNo proxy for:No suitable iRiver iFP device found. Perhaps it is unplugged or turned off.No.Noisy workshopNoneNone of the selected songs has format supported by your player. Do you want to proceed?Note: pre-existing tags will be updated even though they might not be checked here.OSS Audio OfficeOfficial Artist WebsiteOfficial Audio File WebsiteOfficial Audio Source WebsiteOfficial Radio Station WebsiteOgg Speex Ogg Speex (*.spx)Ogg Vorbis Ogg Vorbis (*.ogg)Ogg Xiph CommentsOne or more stores in Music Store have been modified. Do you want to save them before exiting?One song has format unsupported by your player. Do you want to proceed?OpenBSD compatibility, metadata tweaks: Optional features:OrganizationOriginal AlbumOriginal ArtistOriginal FilenameOriginal LyricistOriginal Release TimeOutputOutput:OutputsOverride skin settingsParanoiaParanoia error correctionPathPaths to Music Store databasesPatterns:PausePaymentPerformerPicture type:PlayPlay CD AudioPlay/PausePlayback RVAPlayback RVA is currently disabled. Do you want to enable it now?PlaylistPlaylist DelayPlaylist column orderPlaylist: Please enter a new name.Please enter directory name.Please select a Music Store database.Please select a Programable Title Format File.Please select a local path.Please select at least one valid song from playlist.Please select the audio file for this track.Please select the audio files for this record.Please select the directory for exported files.Please select the directory for ripped files.Please select the download directory for this podcast.Please select the root directory.Please select the xml file for this store.Please specify the file to load the image from.Please specify the file to load the playlist from.Please specify the file to save the image to.Please specify the file to save the playlist to.Podcast URL:Podcast support PodcastsPort:Position: %d%%PreviousPrevious songProcessing metadataProcessing:ProducedProfile: BraindeadProfile: InsaneProfile: RadioProfile: StandardProfile: TelephoneProfile: XtremeProgrammable title format fileProgramming, GUI engineering: ProgressProgress:Protocol for querying (direct connection only):Proxy host:Proxy settingsPublisherPublisher's Official WebsitePublisher/studio logotypePut control buttons at the bottom of playlistQuitRVARVA valuesRead CD+GRead CD-DARead CD-RRead CD-RWRead DVD+RRead DVD+RWRead DVD-RRead DVD-RAMRead DVD-ROMRead DVD-RWRead ISRCRead MCNRead Mode 2 Form 1Read Mode 2 Form 2Read multiple sessionsReadingReading fileReally remove "%s" from the Music Store?Really remove '%s' from the Music Store?Really remove store "%s" from the Music Store?ReasonRecordRecord DateRecord LocationRecord nameRecord name (lowercase)Record titlesRecording location/studioReference volume [dBFS] :RefreshRegular expressionRelease TimeRemoveRemove ArtistRemove RecordRemove StoreRemove TrackRemove allRemove artistRemove deadRemove feedRemove file extensionRemove filesRemove item...Remove non-existing files from storeRemove older items [day]:Remove recordRemove selectedRemove selected songs from playlist (Press right mouse button for menu)Remove storeRemove trackRemoving non-existing filesRenameRename playlistReorder feedsRepeat all songsRepeat current songReplace:Reread data for existing tracksReread file metadataRescanResumeRevision:RipRip CDRip CD...Ripping CD tracksRoll to active songRoot path:Running pluginsRussian: SRC Type: STEREOSample Rate Converter support Sample Rate Converter typeSamplerate:SamplesSamples:SaveSave all playlistsSave all storesSave and closeSave and restore the playlist on exit/startupSave playlistSave playlist periodically [min]:Save storeScanning filesSearchSearch in:Search the Music StoreSearch the PlaylistSearch...SelectSelect a font...Select allSelect all songs in playlist (Press right mouse button for menu)Select directorySelect filesSelect first and close windowSelect juke-box discSelect noneSelected files:Send to iFP deviceSeparateSet drive speedSettingsShow AqualungShow RVA valuesShow active track name in boldShow close button in tabShow cover thumbnail for Music Store tracks onlyShow song name in the main window's titleShow soundfile size in statusbarShow track lengthsShuffle songsSingle channelSizeSkin chooserSkin support, look & feel, GUI hacks: Small timers: SoftwareSong in playlist: Song info: Song title: Sort artists bySort records bySound Files (*.wav, *.aiff, *.au, ...)SourceSource file:Statusbar: StereoStopStop adding filesStop adding songsStructure:Submit CD to CDDB database...Submit new recordSubmit record to CDDB database...Subscribe to new feedSuccessSystray support Tag files with metadataTagging TimeTags to add when creating or updating MPEG audio files:Target directory for ripped filesTarget directory:Target file:The email address provided for submission is invalid.The information below is reported by the drive, and may not reflect the actual capabilities of the device.The selected files will be deleted from the filesystem. No recovery will be possible after this operation. Do you want to proceed?The selected song has format unsupported by your player. Do you want to proceed?The specified store has already been added to the list.The store '%s' already exists. Add it on the Settings/Music Store tab.There are unsaved changes to the file metadata.This Aqualung binary is compiled with:This CD does not contain CD-Text information.This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.TitleTitle FormatTitle appears to be in all lowercase. Do you want to proceed?Title appears to be in all uppercase. Do you want to proceed?Title:Toggle music storeToggle playlistTotalTotal samples:Total: TrackTrack No.Track commentTrack lengthsTrack nameTrack numberTrack titlesTrack:TracksTranslators:Type:URL:Ukrainian: Unable to open fileUnable to remove %d file.Unable to remove %d files.Undo close tabUnknown AlbumUnknown ArtistUnknown RecordUnknown TrackUnknown discUnknown errorUntitledUpdate all feedsUpdate feedUpdate file metadataUpdate file metadata...Updating...Use manual RVA value [dB]Use the local database onlyVBR encodingVendorVendor:Verify data integrityVersionVisible name:Volume level:Volume: %sWarn me if the Window Manager does not support system trayWarningWavPack WavPack (*.wv)When shuffling, records added in Album mode are played in orderWin32 Sound API Write CD-RWrite CD-RWWrite DVD+RWrite DVD+RWWrite DVD-RWrite DVD-RAMWrite DVD-RWWritingYearYear:You have to provide an email address for CDDB submission.You will need to restart Aqualung for the following changes to take effect:_Abort_Add files..._Browse..._Configure_Download_Uploadartistartistsbestcounting...daydaysdrivedrivesencodingfastfeedfeedsfield:iFP device manager (download mode)iFP device manager (upload mode)iRiver iFP driver support itemitemsnew itemnew itemsrrecordrecordsroot / artist / artist / artist / record / trackroot / artist / artist / record / trackroot / artist / record / trackroot / record / trackrwsecondssndfile (WAV) sndfile (WAV, AIFF, etc.) sndio Audio tag:tracktracksProject-Id-Version: Aqualung svn version 1055 Report-Msgid-Bugs-To: POT-Creation-Date: 2009-01-20 09:36+0100 PO-Revision-Date: 2009-01-21 15:42+0100 Last-Translator: Language-Team: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=n != 1; X-Poedit-Language: Swedish X-Poedit-Country: SWEDEN Maximala antalet återförsök: Här borde du skriva in en kommaseparerad lista av domäner som bör kunna kommas åt utan att använda proxyinställningen ovanför. Exempel: localhost, .localdomain, .my.domain.com Musikbiblioteket som du markerade har en matchande artist och album vilket redan innehåller några spår. Om du trycker OK kommer dessa spår att tas bort. Själva filerna kommer att lämnas intakta, men de kommer att tas bort från musikbiblioteket. Tryck Avbryt för att gå tillbaka och ändra Artist/Album eller musikbibliotek. Den fil som du anger/väljer här kommer att användas av Lua-programmet till att formatera titeln. Se Aqualung-manualen för fler detaljer.Här är ett litet exempel på vad du kan skriva i filen: function playlist_title() return m('artist') .. '-' .. m('title') .. ' (' .. m('album') .. ') (' .. i('filename') .. ')' end Strängmallen som du skriver in här kommer att användas för att konstruera en enskild titelrad baserat på ett artist-, skiv- och spårnamn. Dessa betecknas med %%%%a respektive %%%%r och %%%%t. Strängmallen som du skriver in här kommer att användas för att konstruera filnamnet på de exporterade filerna. Artist-, skiv- och spårnamnen kommer att betecknas med %%%%a, %%%%r och %%%%t. The track number and format-dependent file extension are denoted by %%%%n and %%%%x, respectively. The flag %%%%i gives an identifier which is unique within an export session. (%.1f MB) (%d/%d)(kapacitet = %.1f MB) Fritt utrymme (%.1f MB) Markerade: ut V ut H% av standardavvikelse% av standardavvikelse :%.1f MB / %.1f MB%d / %d kataloger%d / %d filer%d dB%d av %d låtar är i ett format som inte stöds av din spelare. Vill du fortsätta?%d%% V%d%% H%ld Hz(Namnlös)(bara ljud)(välj en kategori)(fel uppstod vid inläsning av bild)(ingen kommentar)(ingen beskrivning)(ingen bild)(ingen)*Filinformation*Musikbibliotek100 bildpunkter200 bildpunkter300 bildpunkter50 bildpunkterEnhetsstatusLokal katalogFjärrkatalogInformation om låtarÖverföringsförloppEn stor, färgad fiskALSA Audio APEAvbrytAvbryt pågående uppdateringAvbruten...OmÅtkomstskyddÅtgärd:Aktiv låt i spellista:Lägg tillLägg till artistLägg till skivaLägg till spårLägg till urlLägg till alla objekt till spellistaLägg till alla objekt till spellista (albumläge)Lägg till katalogLägg till filerLägg till filer till spellista (Tryck på höger musknapp för meny)Lägg till objekt...Lägg till ny artist till detta bibliotek...Lägg till ny artist...Lägg till nya objekt till spellistaLägg till nya objekt till spellista (albumläge)Lägg till ny skiva till denna artist...Lägg till ny skiva...Lägg till nytt spår till denna skiva...Lägg till nytt spår...Lägg till i kommentarerLägg till i musikbibliotekLägg till i spellistaLägg till i spellista (albumläge)Lägg till år till kommentarer av nya skivorLägger till filer till spellistaAlbumAlbumbildAlbumläge är standard när hela skivor läggs tillAlbum:AllaAlla ljudfilerAlla filerAlla spellistans filerAlla spårAlla ordVisa alltid flikradenEtt fel inträffade vid försök att ansluta till CDDB-servern.Ett fel inträffade då skivan skulle skickas in till CDDB-servern.UtseendeTillämpa genomsnittligt RVA till spår på samma skivaAqualung är kompilerat med stöd för ikon i systembricka, men statusikonen kunde inte bäddas in i notifieringsytan. Ditt skrivbord har kanske inte stöd för en systembricka, eller så har den inte konfigurerats på rätt sätt.Aqualung är kompilerat utan stöd för LADSPA-insticksmodul. Se Om-rutan och dokumentationen för fler detaljer.Aqualung är kompilerat utan stöd för samplingsfrekvenskonverterare. Se Om-rutan och dokumentationen för fler detaljer.Aqualung-spellista (*.xml)ArtistArtistnamnet ser ut att bara bestå av små bokstäver. Vill du fortsätta?Artistnamnet ser ut att bara bestå av stora bokstäver. Vill du fortsätta?ArtistnamnArtistnamn (små bokstäver)ArtistnamnArtist/album finns redan, inte tomtArtist/sångareArtist:Fråga efter bekräftelse när objekt tas bortBifogad bildLjud-cdLjuddataAudiofilUpphovsmän:Skapa automatiskt spår från dessa filer:Automatisk uppdatering har inaktiverats för alla webbkanaler i poddsändningens bibliotekspopuppmeny.Lägg automatiskt till cd-skivor till spellistaTa automatiskt bort cd-skivor från spellistaUppdatera automatiskt webbkanalerTillgängliga anslutningarTillgängliga insticksmodulerTillgängliga skalGenomsnittBPMOmslagsbild baksidaBalans: %sBand/orkesterBand/artistlogotypBand/orkesterBandbredd:Satsfilsuppdatera filmetadata...BatteriBörjaBibliografiStort tidur:Binärt objektBithastighet [kbps]:BläddraBygg / uppdatera bibliotek från filsystem...Byggversion:Bygg/uppdatera bibliotekBygger musikbibliotek från filsystemMC2-felkorrigeringCd-ljudCd-romhastighet:Stöd för CDDA (ljud-cd) CDDBCDDB (inte tillgänglig)CDDB-letarCDDB-frågaCDDB-fråga efter denna cd...CDDB-fråga efter denna skiva...CDDB-server:CDDB-stöd CDDBP (port 888)Beräkna RVABeräkna volymBeräkna volym (rekursivt)Beräknar volymnivåKan inte skriva till markerad katalog. Var god välj en annan katalog.VersaliseringVersalisera:SkiftlägeskänsligKatalognummerKategoriKategori:BytAntal kanaler:Kanaler:Töm anslutningarTöm listaStängStäng andra flikarStäng flikStäng luckaStäng fönstret när det är klartStäng fönster då överföring är klarFäll in alla objektFärgerKolumnKombinera knapparna spela och pausaKommentarKommentarerKommentarer:Kommersiell informationKompositörKomprimerade moduler (*.bz2)Komprimerade moduler (*.gz)Komprimerade moduler (*.gz, *.bz2)Komprimeringsnivå:Komprimering: Extra hårdKomprimering: SnabbKomprimering: HårdKomprimering: GaletKomprimering: NormalDirigentAnslut via HTTP-proxyAnsluter till CDDB-server...KontaktKonvertera understreck till mellanslagKopiaCopyrightCopyright/juridisk informationGrundläggande formgivning, konstruktion & programmering: Rätta existerande skivaKunde inte läsa in bild från: %sOmslagsbildSkapa en ny katalogSkapa katalogSkapa ett tomt bibliotekSkapa ett tomt bibliotek...Skapa underkataloger för albumSkapa underkataloger för artisterAktuell fil:Klipp ut markeradeDatumDebutalbumAvkodningsstöd:Standardbredd för omslagsbild:Radera hämtade objekt från filsystemBeskrivningBeskrivning:Detektera mediabyteEnheten är upptagen. (Aqualung kunde inte nå dess gränssnitt.)Enheten svarar inte. Try jiggling the handle.Enhetssökväg:Direktanslutning till internetKatalog '%s' kommer att tas bort med hela dess innehåll. Vill du fortsätta?KatalognamnKatalognamn (små bokstäver)KatalogstrukturInaktivera alla insticksmodulerInaktivera manuell utmatningInaktivera skalstödDiskDiskinformationDiskinformation...Förkasta ändringarStäng inteAvsluta inteFörstora inte bilder med mindre breddKoda inte om filer som machar jokertecken:Koda inte om filer som redan är i målformatetVill du spara bibliotek "%s" innan det tas bort från musikbibliotek?Vill du spara biblioteket innan det tas bort?Visa inte omslagsbildsikon i huvudfönstretKlarHämtningskatalog:Hämtar %d/%d (%d%%) ...Drag och släpp poster i listan för att ställa in webbkanalsordningen i musikbiblioteket.Drag och släpp poster i listan nedanför för att ställa in kolumnordningen i spellistan.Cd-rominformationCd-rominformation...Dubbla kanalerVaraktighet:Under framträdandeUnder inspelningEAN/UPCRedigera artistRedigera skivaRedigera bibliotekRedigera spårRedigera artist...Redigera webbkanalRedigera webbkanalsinställningarRedigera objekt...Redigera skiva...Redigera bibliotek...Redigera spår...Mata utE-postadress för uppladdning:Bädda in spellista i huvudfönstretAktivera alla insticksmodulerAktivera RVA-uppspelningAktivera statusmätareAktivera statusmätare i musikbibliotekAktivera statusmätare i spellistaAktivera ikon i systembrickaAktivera verktygsradAktivera verktygsrad i musikbibliotekAktivera verktygstipsAktiveradKodad avKodningstidkodningsstöd:Lägg spellista i köFelFel i formatsträngExkludera filer som matchar jokerteckenExpandera bibliotek vid uppstartExportera alla objekt...Exportera artist...Exportera filerExportera objekt...Exportera nya objekt...Exportera skiva...Exportera bibliotek...Exportera spår...Exporterar filerUtökade titelformatsfiler (*.lua)Utökat data:FLAC-bilderMisslyckades med att ställa in metadata för följande filer:Misslyckades med att skriva metadata till fil. Orsak: %sFilFil '%s' kommer att tas bort. Vill du fortsätta?FilägareFiltypFilformat:Filikon (32x32 PNG)Filikon (annat)FilinformationFilinformation...Filen är inte skrivbarFilnamn:Fil:FilnamnFilnamnsmall:Filnamn:Markerade filer att ta bortFilsystemFilterBara första ordetFöljer katalogstrukturen för att identifiera artisterna och skivorna. The files are added on a record basis.TypsnittTvinga andra bokstäver att skrivas i små bokstäverFormatFormat:Free Lossless Audio Codec (*.flac)Free Lossless Audio Codec (FLAC) Fritt utrymmeOmslagsbild framsidaAllmäntGenreGenre:Tyska: Grafik:HTTP (port 80)HjälpDölj AqualungDölj kommentarpanelDölj kommentatorspanelen för musikbibliotekWebbsida:Ungerska: ID3v1ID3v2ISBNISRCInaktivIllustrationImportera kommentartaggImportera tagg för uppspelningsförstärkning som manuell RVAImportera som ArtistImportera som RVAImportera som SkivaImportera som TitelImportera som SpårnummerImportera som ÅrStora och/eller små bokstäverInkludera bara filer som matchar jokerteckenOberoendeIndataInstrumentInstrument:Internt felInternetNamn på internetradiostationÄgare till internetradiostationTolkad/remixadFältet 'Genre' har ett ogiltigt värdeFältet 'Spårnummer' har ett ogiltigt värdeInvolverade personerDet är väldigt troligt att året är fel. Vill du fortsätta?Italienska: JACK Audio Server JACK-portinställningJACK-anslutning borttappadJACK har antingen stängts av eller så kopplade det från Aqualung för att det inte var tillräckligt snabbt. Det enda du kan göra nu är att starta om både JACK och Aqualung.JACK-portinställningJoint stereoLåt alltid huvudfönstret vara överstBehandlar LADSPA-insticksmodulStöd för LADSPA-insticksmodul LAME (MP3) LAVC (AC3, AAC, WavPack, WMA, etc.) Etikett-idSpråkLayer ILayer IILayer IIISpeltidSpeltid:LicensBegränsningarVardagsrumLäs in spellistaLäs in spellista i en ny flikLäs in inställningar från musikbiblioteksfilLokal CDDB-katalog:PlatsPlats och filnamnLogotyp och ikoner: Stöd för Lua (programmeringsbar titelformatering) Låtskrivare/textskrivareLåtskrivare/textskrivareMIME-typ: %sMOD Audio (MOD, S3M, XM, IT, etc.) MONOMP3-spellista (*.m3u)MPEG Audio (*.mp3, *.mpa, *.mpega, ...)MPEG Audio (MPEG 1-2.5 Layer I-III) Maximalt antal objekt:Maximala antalet återförsök:Maximalt utrymme att använda [MB]:MinnesallokeringsfelMetadataMetadataredigerare (filinformationsdialog)DiverseLäge:Modell:Moduler (*.xm, *.mod, *.it, *.s3m, ...)Monkey's Audio Codec Monkey's Audio Codec (*.ape)StämningMount RainierMultimedia-spellista (*.pls)Musepack Musepack (*.mpc)MusikbibliotekMusikbiblioteksfiler (*.xml)Musikbibliotek:TystaNULLNamnNamn att sortera efter:Namn:Ny flikNästaNästa låtIngen diskIngen matchande skiva hittades.Inget metadata stöder detta formatInget utdataIngen proxy för:Ingen lämplig iRiver iFP-enhet hittades. Kanske är den uttagen eller avstängd.Nej.Bullrig verkstadIngenIngen av de markerade låtarna är i ett format som stöds av din spelare. Vill du fortsätta?Beakta: redan existerande taggar kommer att uppdateras även om de kanske inte är avbockade här.OSS Audio KontorArtistens officiella webbsidaLjudfilens officiella webbsidaLjudkällans officiella webbsidaRadiostationens officiella webbsidaOgg Speex Ogg Speex (*.spx)Ogg Vorbis Ogg Vorbis (*.ogg)Ogg Xiph-kommentarerEn eller flera bibliotek i musikbiblioteket har modifierats. Vill du spara dem innan du avslutar?En låt är i ett format som inte stöds av din spelare. Vill du fortsätta?OpenBSD-kompatibilitet & metadata-finjusteringar: Valbara funktioner:OrganisationUrsprungligt albumUrsprunglig artistUrsprungligt filnamnUrsprunglig låtskrivareUrsprungligt utgivningsdatumUtdataUtdata:UtdataFörbigå skalinställningarParanoiaParanoiafelkorrigeringSökvägSökvägar till musikbiblioteksdatabaserMönster:PausaBetalningSångareBildtyp:SpelaSpela cd-ljudSpela/pausaRVA-uppspelningRVA-uppspelning är för tillfället inaktiverat. Vill du aktivera det nu?SpellistaSpellistefördröjningKolumnordning för spellistaSpellista:Var god skriv in ett namn.Var god skriv in ett katalognamn.Var god välj en musikbiblioteksdatabas.Var god välj en programmeringsbar titelformatsfil.Var god välj en lokal sökväg.Var god välj minst en giltig låt från spellista.Var god välj ljudfilen för denna skiva.Var god välj ljudfilerna för denna skiva.Var god ange katalogen för exporterade filer.Var god ange katalogen för extraherade filer.Var god välj hämtningskatalogen för denna poddsändning.Var god välj rootkatalogen.Var god ange xmlfilen för detta bibliotek.Var god ange filen som bilden ska läsas in från.Var god ange filen som spellistan ska läsas in från.Var god ange filen som bilden ska sparas till.Var god ange filen som spellistan ska sparas till.Poddsändningurl:Stöd för poddsändning PoddsändningarPort:Position: %d%%FöregåendeFöregående låtBehandlar metadataBehandlar:ProduceradProfil: HjärndödProfil: GalenProfil: RadioProfil: StandardProfil: TelefonProfil: ExtremProgrammingsbar titelformatsfilProgrammering & GUI engineering (gags-konstruktion): FörloppFörlopp:Frågeprotokoll (bara direktanslutning):Proxyvärd:ProxyinställningarUtgivareUtgivarens officiell webbsidaUtgivare/studiologotypPlacera kontrollknappar i nederkanten av spellistaAvslutaRVARVA-värdenLäs cd+gLäs cd-daLäs cd-rLäs cd-rwLäs dvd+rLäs dvd+rwLäs dvd-rLäs dvd-ramLäs dvd-romLäs dvd-rwLäs ISRCLäs MCNLäs Mode 2 Form 1Läs Mode 2 Form 2Läs multipla sessionerLäserLäser filVill du verkligen ta bort "%s" från musikbiblioteket?Vill du verkligen ta bort '%s' från musikbiblioteket?Vill du verkligen ta bort bibliotek "%s" från musikbiblioteket?OrsakSkivaInspelningsdatumInspelningsplatsSkivnamnSkivnamn (små bokstäver)SkivtitlarInspelningsplats/studioReferensvolym [dBFS] :UppdateraReguljärt uttryckUtgivningsdatumTa bortTa bort artistTa bort skivaTa bort bibliotekTa bort spårTa bort allaTa bort artistTa bort dödaTa bort webbkanalTa bort filändelseTa bort filerTa bort objekt...Ta bort icke-existerande filer från bibliotekTa bort äldre objekt [dag]:Ta bort skivaTa bort markeradeTa bort markerade låtar från spellista (Tryck höger musknapp för meny)Ta bort bibliotekTa bort spårTar bort icke-existerande filerByt namnByt namn på spellistaOrdna om webbkanalerUpprepa alla låtarUpprepa aktuell låtErsätt:Läs om data för existerande spårLäs om filmetadataUppdateraÅterupptaVersion:ExtraheraExtrahera cdExtrahera cd...Extraherar cd-spårGå till aktiv låtSökväg för root:Kör insticksmodulerRyska: SRC-typ:STEREOStöd för samplingsfrekvenskonverterare SamplingfrekvenskonverterartypSamplingsfrekvens:SamplingarSamplingar:SparaSpara alla spellistorSpara alla bibliotekSpara och stängSpara och återställ spellista vid avslutning/uppstartSpara spellistaSpara spellista periodvis [min]:Spara bibliotekSöker av filerSökSök i:Sök i musikbiblioteketSök i spellistanSök...VäljVälj ett typsnitt...Markera allaMarkera alla låtar i spellista (Tryck höger musknapp för meny)Välj katalogVälj filerVälj först och stäng fönstretVälj jukebox-diskMarkera ingenMarkerade filer:Skicka till iFP-enhetSepareraStäll in cd-romhastighetInställningarVisa AqualungVisa RVA-värdenVisa aktivt spårnamn i fetstilVisa stäng knapp i flikVisa bara omslagsbildsikon för musikbiblioteksspårVisa låtnamn i huvudfönstrets titelVisa ljudfilstorlek i statusmätarenVisa spårspeltiderBlanda låtarEn kanalStorlekSkalväljareSkalstöd, utseende & känsla samt GUI hacks (gags-hack): Små tidur:ProgramvaraLåt i spellista:Låtinformation:Låttitel:Sortera artister efterSortera skivor efterLjudfiler (*.wav, *.aiff, *.au, ...)KällaKällfil:Statusmätare:StereoStoppaSluta lägg till filerSluta lägg till låtarStruktur:Skicka in cd till CDDB-databasen...Skicka in ny skivaSkicka in skiva till CDDB-databasen...Prenumerera på en ny webbkanalSuccéStöd för systembricka Tagga filer med metadataTaggningstidTaggar att lägga till vid skapande eller uppdatering av MPEG-ljudfiler:Målkatalog för extraherade filerMålkatalog:Målfil:E-postadressen som tillhandahölls för uppladdning är ogiltig.Informationen nedan anges av cd-romenheten och kanske inte speglar dess faktiska funktioner.De markerade filerna kommer att raderas från filsystemet. Det går inte att återställa detta efter denna åtgärd. Vill du fortsätta?De markerade låtarna är i ett format som inte stöds av din spelare. Vill du fortsätta?Det angivna biblioteket har redan lagts till i listan.Biblioteket '%s' finns redan. Lägg till det i fliken Inställningar/Musikbibliotek.Det finns osparade ändringar till filmetadatat.Denna Aqualung-binär är kompilerad med:Denna cd innehåller ingen cd-text-information.Följande text är en informell översättning som enbart tillhandahålls i informativt syfte. För alla juridiska tolkningar gäller den engelska originaltexten. Detta program är fri programvara. Du kan distribuera det och/eller modifiera det under villkoren i GNU General Public License, publicerad av Free Software Foundation, antingen version 2 eller (om du så vill) någon senare version. Detta program distribueras i hopp om att det ska vara användbart, men UTAN NÅGON SOM HELST GARANTI, även utan underförstådd garanti om SÄLJBARHET eller LÄMPLIGHET FÖR NÅGOT SPECIELLT ÄNDAMÅL. Se GNU General Public License för ytterligare information. Du bör ha fått en kopia av GNU General Public License tillsammans med detta program. Om inte, skriv till Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.TitelTitelformatTiteln ser ut att bara bestå av små bokstäver. Vill du fortsätta?Titeln ser ut att bara bestå av stora bokstäver. Vill du fortsätta?Titel:Växla musikbibliotekVäxla spellistaTotaltTotalt antal samplingar:Totalt:SpårSpårnummerSpårkommentarSpårspeltiderSpårnamnSpårnummerSpårtitlarSpår:SpårÖversättare:Typ:URL:Ukrainska: Kan inte öppna filKan inte ta bort %d fil.Kan inte ta bort %d filer.Ångra stäng flikOkänt albumOkänd artistOkänd skivaOkänt spårOkänd diskOkänt felNamnlösUppdatera alla webbkanalerUppdatera webbkanalUppdatera filmetadataUppdatera filmetadata...Uppdaterar...Använd manuellt RVA-värde [dB]Använd bara den lokala databasenVBR-kodningTillverkareTillverkare:Bekräfta dataintegritetVersionSynligt namn:Volymnivå:Volym: %sVarna mig om fönsterhanteraren inte stöder visning av ikon i systembrickaVarningWavPack WavPack (*.wv)När funktionen blanda används spelas skivor tilllagda i albumläge i ordningWin32 Sound API Skriv cd-rSkriv cd-rwSkriv dvd+rSkriv dvd+rwSkriv dvd-rSkriv dvd-ramSkriv dvd-rwSkriverÅrÅrDu måste tillhandahålla en e-postadress för att ladda upp till CDDB.Du kommer att behöva starta om Aqualung för att de följande ändringarna ska börja gälla:_Avbryt_Lägg till filer..._Bläddra..._Konfigurera_Hämta_Skickaartistartisterbästräknar...dagdagarcd-romcd-romenheterkodningsnabbwebbkanalwebbkanalerfält:iFP-enhetshanterare (hämtningsläge)iFP-enhetshanterare (uppladdningsläge)Stöd för iRiver iFP-drivrutin objektobjektnytt objektnya objektskrivskyddadskivaskivorroot / artist / artist / artist / skiva / spårroot / artist / artist / skiva / spårroot / artist / skiva / spårroot / skiva / spårläs och skrivsekundersndfile (WAV) sndfile (WAV, AIFF, etc.) sndio Audio tagg:spårspåraqualung-0.9beta11/src/po/uk.mo0000644000175000001440000026550511331334313013303 00000000000000$,<8P9P4UPP/Q+MRFyT2U5V)X[X >ZIZRZhZ ~ZZZZZZZ ZZO[T[[[b[ i[ t[[[ [[ [[ [ [ [ [ \ \\3\J\b\t\\ \\\\ \\\\\\] ] !] ,]6]>]&X] ] ]9] ]]]^(^&B^ i^^^^^^^_'_E_^_d_ u_4____ __ _ _`A`A]` `/``hapbbb>b>b $c0c Hc(Uc~cc(ccRc$d -d 8dCdLd$hdRd!d&e")eLege}eeee e eeee e;f H S ] h s  Ð֐ ((>.g  ̑  Ò˒   , : G T _ m y $͓ G* r  ͔ޔ'E[4qҕ! 7 ANR Ycu  ɖ  (-@P-_ ! ȗח ޗ % 6@A И  *: CQa02ʙ) '+Ht #Ț ͚&ښ , 8EU&e  Лכܛ  +I![} ǜ ߜ7!$F Xe5jj Q7F/`&-  Ģ=բ=QXt ģ ң  * KQ Vbv#ޤ  .5<2r ,  % 6BW oC{ ٦( 9FMUks :V ?b ʨ ֨  9KW é Ωة  !-16<CLQV\"c ªǪͪ ֪0'"Ji ƫ̫ ӫ߫?68\o̭ sϵCY&ܼ> BO!X$z68=Sn"*2;O#i>! "%/Ut (*-<&j( 4(@ IVB^ Mia3N/;OkkH'%pD'&3*5^QGH. w4# lz7;hMg l+k"rt`:!-OO!\'4\ , =9KNSxST :u"%$(HY,q Dd2XC2B .O^"a%(*#4N''>0S=/M%}((:c" "LB&Qx9J(7`oE)9%N$t+5) % F(g&.1*)'T|kWETCQ.aE**61a?C2PT]*{B[E NX&omdi6y,:g;%,=6R2$'0HJ^U^^y}ObG()#P&t[ !B]'e##*# :D&"&&E&Sl"[*jU<((MQO08 ]Y#9*?&YDf+;>g"I=[Q-$"/?o UB_`uX/8N`z#"$$06g ~#1  )"6Y }!S  ""!Eg#,  ,.?n4T !1Bt)#$&,;0hU.,&K@r&." ,TL  !94J8' 3@ 0` !  V  2 (P *y  (   J  I *T $ -  $ % ) = F  O  Y 0d  L   .?&H$o0:U_g';DAc(2^ ` #/'$7"\ =5H b/mW $ / ;(I,r+ %=+S0 24Q!q$#;W2mQ8 C%  4?;H=BA GR dpG+E(Mv01,)(Gp y3   6(Fbdkd C5!y! ! !C!!8!5" R"]"q"0"&" "`"#M#4q#E#%#6$AI$X$v$@[%z%V&Xn&b&U*'o'F'N7(q((\y)m)D*&Z** **N*J+9K+++!+++!,&&,M, h,,,*,Q,5@-v--O--%.$&.K.7\.*. .N. / %/B2/u////////0#080_L0000*0(171JQ1J1Y1A2 P2[2q22722$2 3:=4x4Y4 44&565N5#_55555#56960Y66"6/6B6@<7}777b88488>8/19(a909 9v9S@:T:v:S`;Z;<%<D;<0<<<4<="=<=!X=$z=)=3==%>@> U> b>o>R~>K>*?H?[?q??;?&?$?m@4@X@A!9A [AhA,yA3AAAAB*B"BBC8 C.YCCC,C C-C6DVDoD%D;DFD2ErE^(FOFnF4FG{GLGG G Hl#H HH3H'HI,6I$cI4III-IJ4J SJ`J0iJ0JJHJM(K(vK>K3KL+L:LML3kL+L LhLIUM&M MMiMZNNODePPF5Q7|Q@Q0Q<&RAcW WW,WbWdXX X;X0Y26Y iYtY YYYYYZZ9ZSZcZrZkZZZ[,[0H[3y[2[@[3!\U\h\'\\\N\K=]]]~]D^2Y^^^$^^*^/%_U_k_?`WF`L`!` a5(a^awa4a a-abb6bwKbbbbbc+d; U&GTe\ +k 64%4WoZP_|: mDCJ< ;!>lN/Dy^dJZ*^#:@m81dFp9_p`76OlLgv}n)GRidYbFha!B l|'5 # yMaO\Qft}v@/c3 08 ;{Nz1rXOP^bTW7\]LWCa:c@NDu"]MnRE`xhre(rZEo/6ijK'X<wp~.Lg:OjJ2F?.5.jVE`TX1f>pmQ"= A9zV)UA~<$qH3[jnE%Z GG,Y06u+ sQ4+&; $K[$q*3'Sz_i< -Q9 wIMA=l}gI02#n)yqfmIb]TMWK%i u,!A)CN9vo7Ic4-u>hteHR[ x70 Maximum number of retries: Destination directory is not read-write accessible! Here you should enter a comma-separated list of domains that should be accessed without using the proxy set above. Example: localhost, .localdomain, .my.domain.com Most drives let Aqualung know when a CD has been inserted or removed by providing a 'media changed' flag. However, some drives don't set this flag properly, and thus it may happen that a newly inserted CD remains unnoticed to Aqualung. In such cases, enabling this option should help. Set the drive speed for CD playing in CD-ROM speed units. One speed unit equals to 176 kBps raw data reading speed. Warning: not all drives honor this setting. Lower speed usually means less drive noise. However, when using Paranoia error correction modes for increased accuracy, generally much larger speeds are required to prevent buffer underruns (and thus audible drop-outs). Please note that these settings do not apply to CD Ripping, which always happens with maximum available speed and with error correction modes manually set before every run. The Music Store you selected has a matching Artist and Album, already containing some tracks. If you press OK, these tracks will be removed. The files themselves will be left intact, but they will be removed from the destination Music Store. Press Cancel to get back to change the Artist/Album or the destination Music Store. The file you enter/choose here will set the Lua program to use to format the title. See the Aqualung manual for details. Here is a quick example of what you can use in the file: function playlist_title() return m('artist') .. '-' .. m('title') .. ' (' .. m('album') .. ') (' .. i('filename') .. ')' end The string you enter here will be parsed as a command line before parsing the actual command line parameters. What you enter here will act as a default setting and may or may not be overridden from the 'real' command line. Example: enter '-o alsa -R' below to use ALSA output running realtime as a default. The template string you enter here will be used to construct a single title line from an Artist, a Record and a Track name. These are denoted by %%%%a, %%%%r and %%%%t, respectively. The template string you enter here will be used to construct the filename of the exported files. The Artist, Record and Track names are denoted by %%%%a, %%%%r and %%%%t. The track number and format-dependent file extension are denoted by %%%%n and %%%%x, respectively. The flag %%%%i gives an identifier which is unique within an export session. (%.1f MB) (%d/%d) (capacity = %.1f MB) Free space (%.1f MB) Selected: out L out R% of standard deviation% of standard deviation :%.1f MB / %.1f MB%d / %d directories%d / %d files%d dB%d of %d songs have format unsupported by your player. Do you want to proceed?%d%% L%d%% R%ld Hz(Untitled)(audio only)(choose a category)(error loading image)(no comment)(no description)(no image)(none)*File info*Music Store100 pixels200 pixels300 pixels50 pixelsDevice statusLocal directoryRemote directorySongs infoTransfer progressA large, coloured fishALSA Audio APEAbortAbort ongoing updateAborted...AboutAbstractAccessAction:Active song in playlist: AddAdd ArtistAdd RecordAdd TrackAdd URLAdd all items to playlistAdd all items to playlist (Album mode)Add directoryAdd filesAdd files to playlist (Press right mouse button for menu)Add item...Add mouse button commandAdd new artist to this store...Add new artist...Add new items to playlistAdd new items to playlist (Album mode)Add new record to this artist...Add new record...Add new track to this record...Add new track...Add to CommentsAdd to Music StoreAdd to playlistAdd to playlist (Album mode)Add year to the comments of new recordsAdding files to PlaylistAlbumAlbum Sort OrderAlbum imageAlbum mode is the default when adding entire recordsAlbum:AllAll Audio FilesAll FilesAll Playlist FilesAll tracksAll wordsAlways show the tab barAn error occurred while attempting to connect to the CDDB server.An error occurred while submitting the record to the CDDB server.AppearanceApply averaged RVA to tracks of the same recordAqualung is compiled with system tray support, but the status icon could not be embedded in the notification area. Your desktop may not have support for a system tray, or it has not been configured correctly.Aqualung is compiled without LADSPA plugin support. See the About box and the documentation for details.Aqualung is compiled without Sample Rate Converter support. See the About box and the documentation for details.Aqualung playlist (*.xml)ArtistArtist appears to be in all lowercase. Do you want to proceed?Artist appears to be in all uppercase. Do you want to proceed?Artist nameArtist name (lowercase)Artist namesArtist/Album already existing, not emptyArtist/performerArtist:Ask for confirmation when removing itemsAttached PictureAttached Picture frame with no image set! Please set an image or remove the frame.Audio CDAudio dataAudiophileAuthors:Auto-check interval [hour]:Auto-create tracks from these files:Automatic update has been disabled for all feeds in the Podcasts store popup menu.Automatically add CDs to PlaylistAutomatically remove CDs from PlaylistAutomatically roll to active trackAutomatically update feedsAvailable connectionsAvailable pluginsAvailable skinsAverageBPMBack coverBalance: %sBand/OrchestraBand/artist logotypeBand/orchestraBandwidth:Batch update & encode (mass tagger, CD ripper, file export)Batch-update file metadata...BatteryBeginBibliographyBig timer: Binary ObjectBitrate [kbps]:BrowseBuild / Update store from filesystem...Build version: Build/Update storeBuilding store from filesystemBurn ProofButtonCC2 Error CorrectionCD AudioCD drive speed:CDDA (Audio CD) support CDDBCDDB (not available)CDDB lookupCDDB queryCDDB query for this CD...CDDB query for this record...CDDB server:CDDB support CDDBP (port 888)Calculate RVACalculate volumeCalculate volume (recursive)Calculating volume levelCannot write to selected directory. Please select another directory.CapitalizationCapitalize: Case sensitiveCatalog NumberCategoryCategory:ChangeChange balanceChange current songChange song positionChange volumeChannel count:Channels:Clear connectionsClear listClick here to set mouse buttonCloseClose other tabsClose tabClose trayClose window when completeClose window when transfer completeCollapse all itemsColorsColumnCombine play and pause buttonsCommandCommentCommentsComments:Commercial InformationComposerCompressed modules (*.bz2)Compressed modules (*.gz)Compressed modules (*.gz, *.bz2)Compression level:Compression: Extra HighCompression: FastCompression: HighCompression: InsaneCompression: NormalConductorConnect via HTTP proxyConnecting to CDDB server...Connection timeout [sec]:ContactContent GroupConversion error in field %s: '%s' does not conform to format '%s'!Conversion to target charset failedConvert underscore to spaceCopyCopyrightCopyright/Legal InformationCore design, engineering & programming: Correct existing recordCould not load image from: %sCover artCreate a new directoryCreate directoryCreate empty storeCreate empty store...Create subdirectories for albumsCreate subdirectories for artistsCurrent file: Cut selectedDSPDateDebut AlbumDecoding support:Default cover width:Delete downloaded items from the filesystemDescriptionDescription:DestinationDetect media changeDevice is busy. (Aqualung was unable to claim its interface.)Device is not responding. Try jiggling the handle.Device path:Direct connection to the InternetDirectory '%s' will be removed with its entire contents. Do you want to proceed?Directory drivenDirectory nameDirectory name (lowercase)Directory structureDisable all pluginsDisable control buttons reliefDisable manual ejectDisable skin supportDiscDisc infoDisc info...Discard changesDo not closeDo not exitDo not magnify images with smaller widthDo not reencode files matching wildcard:Do not reencode files already being in the target formatDo nothingDo you want to save store "%s" before removing from Music Store?Do you want to save the store before removing?Don't show cover thumbnail in the main windowDoneDownload directory:Downloading %d/%d (%d%%) ...Drag and drop entries in the list to set the feed order in the Music Store.Drag and drop entries in the list below to set the column order in the Playlist.Drive infoDrive info...Drop statistical aberrations based onDual channelDuration:During performanceDuring recordingEAN/UPCEdit ArtistEdit RecordEdit StoreEdit TrackEdit artist...Edit feedEdit feed settingsEdit item...Edit record...Edit store...Edit track...EjectEmail address for submission:Embed playlist into main windowEmphasis:Emphasis: noneEmphasis: reservedEnable Music Store tree node iconsEnable all pluginsEnable playback RVAEnable rules hintEnable statusbarEnable statusbar in Music StoreEnable statusbar in playlistEnable systrayEnable toolbarEnable toolbar in Music StoreEnable tooltipsEnable tree node iconsEnabledEncoded byEncoding TimeEncoding support:Enqueue playlistErrorError converting field %s to Year: '%s' is not an integer number!Error in format stringError in title format stringExact matches onlyExclude files matching wildcardExpand Stores on startupExpected '}' after '{', but end of string found.Export all items...Export artist...Export filesExport item...Export new items...Export record...Export store...Export track...Exporting filesExtended Title Format Files (*.lua)Extended data:FLAC PicturesFailed to set metadata for the following files:Failed to write metadata to file. Reason: %sFileFile "%s" does not exist or your write permission has been withdrawn. Check if the partition containing the store file has been unmounted.File '%s' will be removed. Do you want to proceed?File OwnerFile TypeFile format:File icon (32x32 PNG)File icon (other)File infoFile info...File is not writableFile name: File:FilenameFilename template:Filename:Files selected for removalFilesystemFilterFirst word onlyFollows the directory structure to identify the artists and records. The files are added on a record basis.FontsForce TOC re-read on every drive scanForce case: Force other letters to lowercaseFormatFormat:Free Lossless Audio Codec (*.flac)Free Lossless Audio Codec (FLAC) Free spaceFrench: Front coverGeneralGeneric StreamMetaGenreGenre:German: Graphics:HTTP (port 80)Hard reset deviceHelpHide AqualungHide comment paneHide the Music Store comment paneHomepage:Horizontal mouse wheel:Hungarian: IDID3v1ID3v2ISBNISRCIcy-DescriptionIcy-GenreIcy-NameIdleIllustrationImplicit command lineImport Comment tagImport Replaygain tag as manual RVAImport as ArtistImport as RVAImport as RecordImport as Sort KeyImport as TitleImport as Track No.Import as YearIn any caseInclude only files matching wildcardIndependentIndexInitial keyInputsInstrumentsInstruments:Internal errorInternetInternet Radio Station NameInternet Radio Station OwnerInterpreted/RemixedIntroplayInvalid 'Genre' field valueInvalid 'Track no.' field valueInvert current stateInvert selectionInvolved PeopleIt is very likely that the year is wrong. Do you want to proceed?Italian: JACK Audio Server JACK Port SetupJACK connection lostJACK has either been shutdown or it disconnected Aqualung because it was not fast enough. All you can do now is restart both JACK and Aqualung.JACK port setupJapanese: Joint stereoKeep main window always on topKey: LADSPA patch builderLADSPA plugin processingLADSPA plugin support LAME (MP3) LAVC (AC3, AAC, WavPack, WMA, etc.) LAVC audio/video filesLabel CodeLanguageLayer ILayer IILayer IIILead artist/performerLeaflet pageLeft and right mouse buttons are reserved.Left buttonLengthLength:LicenseLimitsLinear threshold [dB]Linear threshold [dB] :Listening environment:Living roomLoad playlistLoad playlist in new tabLoad settings from Music Store fileLocal CDDB directory:LocationLocation and filenameLogo, icons: Loop playback support Loop range: %d-%d%%Loop range: %d-%d%% [%s - %s]Lua (programmable title formatting) support Lyricist/Text WriterLyricist/text writerMIME type: %sMOD Audio (MOD, S3M, XM, IT, etc.) MONOMP3 Playlist (*.m3u)MPEG Audio (*.mp3, *.mpa, *.mpega, ...)MPEG Audio (MPEG 1-2.5 Layer I-III) MPEG StreamMetaMain windowMatches:Maximum number of items:Maximum number of retries:Maximum space to use [MB]:MediaMemory allocation errorMetadataMetadata editor (File info dialog)Middle buttonMiscellaneousMode:Model:Module infoModules (*.xm, *.mod, *.it, *.s3m, ...)Monkey's Audio Codec Monkey's Audio Codec (*.ape)MoodMount RainierMouse buttonMouse buttonsMouse wheelMovie/video screen captureMultimedia Playlist (*.pls)Musepack Musepack (*.mpc)Musepack ReplayGainMusic StoreMusic Store Files (*.xml)Music Store: Musician CreditsMuteNULLNameName to sort by:Name transformationName:New tabNextNext songNo discNo matching record found.No metadata support for this formatNo outputNo proxy for:No suitable iRiver iFP device found. Perhaps it is unplugged or turned off.No.Noisy workshopNoneNone of the selected songs has format supported by your player. Do you want to proceed?Note: pre-existing tags will be updated even though they might not be checked here.OSS Audio OfficeOfficial Artist WebsiteOfficial Audio File WebsiteOfficial Audio Source WebsiteOfficial Radio Station WebsiteOgg Speex Ogg Speex (*.spx)Ogg Vorbis Ogg Vorbis (*.ogg)Ogg Xiph CommentsOne or more stores in Music Store have been modified. Do you want to save them before exiting?One song has format unsupported by your player. Do you want to proceed?Only if unmeasuredOpenBSD compatibility, metadata tweaks: Optional features:OrganizationOriginal AlbumOriginal ArtistOriginal FilenameOriginal LyricistOriginal Release TimeOtherOutputOutput driver support:Output:OutputsOverall: Override skin settingsParanoiaParanoia error correctionPart Of A SetPathPaths must either be absolute or starting with a tilde, which will be expanded to the user's home directory. Drag and drop entries in the list to set the store order in the Music Store.Paths must either be absolute or starting with a tilde.Paths to Music Store databasesPatterns:PausePaymentPerform overlapped readsPerformerPerformer Sort OrderPicture type:PlayPlay CD AudioPlay/PausePlay/Pause songPlay/Stop songPlayback RVAPlayback RVA is currently disabled. Do you want to enable it now?PlaylistPlaylist DelayPlaylist column orderPlaylist: Please enter a new name.Please enter directory name.Please select a Music Store database.Please select a Programable Title Format File.Please select a local path.Please select at least one valid song from playlist.Please select the audio file for this track.Please select the audio files for this record.Please select the directory for exported files.Please select the directory for ripped files.Please select the download directory for this podcast.Please select the root directory.Please select the xml file for this store.Please specify the file to load the image from.Please specify the file to load the playlist from.Please specify the file to save the image to.Please specify the file to save the playlist to.Podcast URL:Podcast support PodcastsPort:Position: %d%%Post Fader (after Volume & Balance)Pre Fader (before Volume & Balance)Predefined transformationsPreviousPrevious songProcessing metadataProcessing:ProducedProfile: BraindeadProfile: InsaneProfile: RadioProfile: StandardProfile: TelephoneProfile: ThumbProfile: XtremeProgrammable title format fileProgramming, GUI engineering: ProgressProgress:Protocol for querying (direct connection only):Proxy host:Proxy settingsPublication RightPublisherPublisher's Official WebsitePublisher/studio logotypePulseAudio Put control buttons at the bottom of playlistQuitRVARVA for Unmeasured Files [dB] :RVA valuesRead CD+GRead CD-DARead CD-RRead CD-RWRead DVD+RRead DVD+RWRead DVD-RRead DVD-RAMRead DVD-ROMRead DVD-RWRead ISRCRead MCNRead Mode 2 Form 1Read Mode 2 Form 2Read multiple sessionsReadingReading fileReally remove "%s" from the Music Store?Really remove '%s' from the Music Store?Really remove store "%s" from the Music Store?ReasonRecordRecord DateRecord LocationRecord nameRecord name (lowercase)Record titlesRecording location/studioRecursive search from the root directory for audio files. The files are processed independently, so only metadata and filename transformation are available.Reference volume [dBFS] :RefreshRegexp matches empty stringRegexp:Regular expressionRelatedRelease TimeRemoveRemove ArtistRemove RecordRemove StoreRemove TrackRemove allRemove artistRemove deadRemove feedRemove file extensionRemove filesRemove item...Remove leading numberRemove non-existing files from storeRemove older items [day]:Remove recordRemove selectedRemove selected songs from playlist (Press right mouse button for menu)Remove storeRemove trackRemoving non-existing filesRenameRename playlistReorder feedsRepeat all songsRepeat current songReplace:ReplayGain Album GainReplayGain Album PeakReplayGain Reference LoudnessReplayGain Track GainReplayGain Track PeakReplayGain tag to use (with fallback to the other): Replaygain_album_gainReplaygain_track_gainReread data for existing tracksReread file metadataRescanResumeRetrieving matches from server...Revision:Right buttonRipRip CDRip CD...Ripping CD tracksRoll to active songRoot path:Running pluginsRussian: SRC Type: STEREOSTOPPINGSample Rate Converter support Sample Rate Converter typeSamplerate:SamplesSamples:SandboxSaveSave all playlistsSave all storesSave and closeSave and restore the playlist on exit/startupSave playlistSave playlist periodically [min]:Save storeScanning filesSearchSearch in:Search the Music StoreSearch the PlaylistSearch...SelectSelect a font...Select allSelect all songs in playlist (Press right mouse button for menu)Select build typeSelect directorySelect filesSelect first and close windowSelect juke-box discSelect noneSelected files:Send to iFP deviceSeparateSet SubtitleSet drive speedSettingsShow AqualungShow RVA valuesShow active track name in boldShow close button in tabShow cover thumbnail for Music Store tracks onlyShow hidden files and directories in file choosersShow song name in the main window's titleShow soundfile size in statusbarShow tags tab first in the file info dialogShow track lengthsShuffle songsSimple view in LADSPA patch builderSingle channelSizeSkin chooserSkin support, look & feel, GUI hacks: Small timers: SoftwareSong in playlist: Song info: Song title: Sort artists bySort records bySound Files (*.wav, *.aiff, *.au, ...)SourceSource file:Start minimizedStatusbar: Steepness [dB/dB] :StereoStopStop adding filesStop adding songsStructure:Subdirectory name length limit:Submit CD to CDDB database...Submit new recordSubmit record to CDDB database...Subscribe to new feedSubtitleSuccessSwedish: SystraySystray support Tag files with metadataTagging TimeTags to add when creating or updating MPEG audio files:Target directory for ripped filesTarget directory:Target file:TestThe email address provided for submission is invalid.The information below is reported by the drive, and may not reflect the actual capabilities of the device.The selected files will be deleted from the filesystem. No recovery will be possible after this operation. Do you want to proceed?The selected song has format unsupported by your player. Do you want to proceed?The specified store has already been added to the list.The store '%s' already exists. Add it on the Settings/Music Store tab.There are unsaved changes to the file metadata.This Aqualung binary is compiled with:This CD does not contain CD-Text information.This button is already assigned.This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.Timeout for socket I/O:TitleTitle FormatTitle Sort OrderTitle appears to be in all lowercase. Do you want to proceed?Title appears to be in all uppercase. Do you want to proceed?Title:Toggle LADSPA patch builderToggle music storeToggle playlistTotalTotal samples:Total: TrackTrack No.Track commentTrack lengthsTrack nameTrack numberTrack titlesTrack:TracksTranslators:Trim leading, tailing and duplicate spacesType:URL:Ukrainian: Unable to open fileUnable to remove %d file.Unable to remove %d files.Undo close tabUnexpected end of string after '?'.United windows minimizationUnknownUnknown AlbumUnknown ArtistUnknown RecordUnknown TrackUnknown conversion type character found after '%%%%'.Unknown conversion type character found after '?'.Unknown discUnknown errorUnlimited retry on failed reads (never skip)UnmeasuredUnmeasured tracks onlyUnrecognizedUntitledUpdate all feedsUpdate feedUpdate file metadataUpdate file metadata...Updating...Use basename only instead of full path if no metadata is available.Use manual RVA value [dB]Use relative paths in store fileUse the local database onlyUser Defined TextUser Defined URLVBR encodingVendorVendor:Verify data integrityVersionVertical mouse wheel:Visible name:Volume level:Volume: %sWarn me if the Window Manager does not support system trayWarningWavPack WavPack (*.wv)When adding new frames, try to set their contents from another tag's equivalent frame.When shuffling, records added in Album mode are played in orderWin32 Sound API Write CD-RWrite CD-RWWrite DVD+RWrite DVD+RWWrite DVD-RWrite DVD-RAMWrite DVD-RWWritingYearYear:You have to provide an email address for CDDB submission.You will need to restart Aqualung for the following changes to take effect:_Abort_Add files..._Browse..._Configure_Download_Uploadartistartistsbestbit doublebit floatbit signedbit unsignedcounting...daydaysdrivedrivesencodingfastfeedfeedsfield:iFP device manager (download mode)iFP device manager (upload mode)iRiver iFP driver support itemitemsnew itemnew itemsrrecordrecordsroot / artist / artist / artist / record / trackroot / artist / artist / record / trackroot / artist / record / trackroot / record / trackrwsecondssndfile (WAV) sndfile (WAV, AIFF, etc.) sndio Audio tag:tracktracksunreachableuse browser window widthProject-Id-Version: aqualung 0.9beta10 Report-Msgid-Bugs-To: POT-Creation-Date: 2010-01-17 16:11+0200 PO-Revision-Date: 2010-01-17 16:14+0300 Last-Translator: Vladimir Smolyar Language-Team: Ukrainian MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Максимальна кількість спроб: Вказаний каталог не доступний для читання/запису! Тут ви маєте увести через кому список доменів, доступ до яких має здійсньватися без використання проксі, встановленого вище. Приклад: localhost, .localdomain, .my.domain.com Більшість пристроїв дають Aqualung'у знати, коли вставлено або вилучено CD, встановлюючи прапор 'носій змінено'. Однак, деякі пристрої не втановлюють цей флаг належним чином, і тому щойно вставлений CD може лишитися непоміченим Aqualung'ом. В таких випадках увімкнення цієї функції має допомогти. Встановіть швидкість приводу для програвання CD в одиницях швидкості CD-ROM. Одна одиниця швидкості відповідає швидкості читання даних 176 кбіт/с. Попередження: не всі пристрої приймають це налаштування. Нижча швидкість зазвичай означає менше галасу з боку приводу. Однак, коли використовуються режими корекції помилок Paranoia для підвищення точності, звичайно потрібні набагато більші швидкості, аби запобігти спустошенню буфера (і як наслідок - чутних випадань). Будь ласка, зауважте, що ці налаштування не впливають на діставання музики з CD (Ripping), яке завжди відбувається на максимально можливій швидкості та з ручним встановленням режимів корекції помилок перед кожним сеансом. В обраному вами Музичному Сховищі вже є виконавець та альбом, що містить доріжки. Якщо ви натиснете Если вы нажмете ОК, ці треки буде видалено. Файли самі по собі будуть залишені непошкодженими, але вони будуть видалені з даного Музичного Сховища. Нажмите Відміна для повернення до зміни виконавця/альбома або выбору іншого Музичного Сховища. Файл, що ви уведете/оберете тут, встановить програму на Lua, що буде використана для форматування заголовка. Для додаткової інформації див. довідку з Aqualung. Ось швидкий прклад того, що ви можете використовувати у цьому файлі: function playlist_title() return m('artist') .. '-' .. m('title') .. ' (' .. m('album') .. ') (' .. i('filename') .. ')' end Рядок, що ви введете тут буде проаналізовано як командний рядок перед аналізом параметрів справжнього командного рядку. Те, що ви впишете тут, буде діяти як налаштування за замовчуванням, та може бути або не бути скасовано 'справжнім' командним рядком. Приклад: впишіть '-o alsa -R' нижче для використання виводу через ALSA у реальному часі за замовчуванням. Рядки шаблону, що ви впишете сюди, буде використано для складання однієї назви з Виконавця, Запису та назви Доріжки. Вони позначаються %%%%a, %%%%r та %%%%t, відповідно. Рядки шаблону, що ви впишете сюди, буде використано для складання ім'я експортованих файлів. Ім'я Виконавця, Запису та Доріжки позначаються %%%%a, %%%%r та %%%%t. Номер доріжки та розширення файлу, що залежить віз формату, позначаються %%%%n та %%%%x, відповідно. Прапор %%%%i дає ідентифікатор, унікальний у межах сеансу експорту. (%.1f МБ) (%d/%d) (місткість = %.1f МБ) ВІльне місце (%.1f МБ) Обрані: вихід Л вихід П% від стандартного відхилення% від стандартного відхилення :%.1f МБ / %.1f МБ%d / %d каталогів%d / %d файлів%d Дб%d з %d пісень мають формат, що не підтримується вашиим плеєром. Бажаєте продовжити?%d%% Л%d%% П%ld Гц(Без назви)(тільки аудіо)(оберіть категорію)(помилка завантаження зображення)(без коментаря)(немає опису)(немає зображення)(немає)*Інформація про файл*Музичне Сховище100 пікселів200 пікселів300 пікселів50 пікселівСтан пристроюЛокальний каталогВіддалений каталогІнформація про пісніПрогрес передачіВелика кольорова рибаALSA Audio APEПерерватиПерервати поточне оновленняСкасовано...Про програмуОписДоступДія:Активна пісня у списку програвання: ДодатиДодати виконавцяДодати записДодати доріжкуДодати URLДодати усі елементи до списку програванняДодати усі елементи до списку програвання (режим альбому)Додати каталогДодати файлиДодати файли до списку програвання (Натисніть праву кнопку миші для відкриття меню)Додати елемент...Додати команду клавіші мишіДодати нового виконавця до цього сховища...Додати нового виконавця...Додати нові елементи до списку програванняДодати нові елементи до списку програвання (режим альбому)Додати новий запис до цього виконавця...Додати новий запис...Додати нову доріжку до цього запису...Додати нову доріжку...Додати до коментарівДодати до Музичного СховищаДодати до списку програванняДодати до списку програвання (режим альбому)Додати рік до коментарів нових записівДодавання файлів до списку програванняАльбомПорядок сортування альбомівЗображення альбомуРежим альбому використовується за замовчуванням при додаванні цілих записівАльбом:УсеУсі аудіофайлиУсі файлиУсі файли списків програванняУсіх доріжокУсі словаЗавжди показувати рядок вкладокПід час спроби під'єднання до сервера CDDB виникла помилка.Під час надсилання запису до сервера CDDB виникла помилка.ВиглядЗастосувати усереднений рівень RVA до доріжок одного записуAqualung скомпільовано з підтримкою системного лотка, але статусна іконка не може бути вбудована у область повідомлень. Можливо, ваш робочий стіл не підтримує системний лоток, або невірно налаштований.Aqualung скомпільовано без підтримки додатків LADSPA. Дивись вікно 'Про програму' та документацію для подробиць.Aqualung скомпільовано без підтримки Перетворювача Частоти Дискретизації. Дивись вікно 'Про програму' та документацію для подробиць.Плей-ліст Aqualung (*.xml)ВиконавецьІм'я виконавця цілком у нижньому регістрі. Бажаєте продовжити?Ім'я виконавця цілком у верхньому регістрі. Бажаєте продовжити?Ім'ям виконавцяІм'ям виконавця (нижній регістр)Іменах виконавцівВиконавець/Альбом вже існують та непорожніСпівак/виконавецьВиконавець:Запитувати підтвердження при видаленні елементівПрикріплена картинкаПрикріплена картинка без зображення! Будь ласка, встановіть зображення або видаліть картинку.Аудіо CDАудіо даніАудіофілАвтори:Інтервал автомеревірки [годин]:Автоматично створити доріжки з цих файлів:Автоматичне оновлення заборонено для усіх стрічок у спливаючому меню сховища подкастів.Автоматично додавати CD до списку програванняАвтоматично видаляти CD зі списку програванняАвтоматично переміщатися до активної доріжкиАвтоматично оновлювати стрічкиДоступні з'єднанняДоступні розширенняНаявні жупаниСереднійBPMЗадня обкладинкаБаланс: %sГурт/оркестрЛоготип гурту/виконавцяГурт/оркестрПотік:Пакетне оновлення та кодування (масове заповнення тегів, діставання з CD, експорт файлів)Пакетне оновлення метаданих файлів...БатареяПочатокБібліографіяВеликий таймер: Бінарний об'єктБітрейт [kbps]:ОглянутиПобудувати/Оновити сховище з файлової системи...Версія збірки: Побудувати/Оновити сховищеПобудова сховища з файлової системиЗахист від записуКлавішаЦКорекція помилок C2CD AudioШвидкість приводу CD:Підтримка CDDA (Аудіо CD) CDDBCDDB (недосяжний)Пошук у CDDBЗапит у CDDBЗапит у CDDB для цього CD...Запит у CDDB для цього запису...Сервер CDDB:Підтримка CDDB CDDBP (порт 888)Підрахувати рівень RVAПідрахувати гучністьПідрахувати гучність (рекурсивно)Підрахунок рівня гучностіНеможливо записани до обраного каталога. Будь ласка, оберіть інший каталог.Перетворення до заголовних літерПеретворити на заголовні:Враховувати регістрНомер каталогаКатегоріяКатегорія:ЗмінитиЗмінити балансЗмінити поточну піснюЗмінити позицію пісніЗмінити гучністьКількість каналів:Канали:Очистити з'єднанняОчистити списокКлацніть тут, щоб встановити клавішу мишіЗакритиЗакрити інші вкладкиЗакрити вкладкуЗачинити лотокЗакрити вікно після завершенняЗакрити вікно після завершення передачіЗгорнути усі елементиКольориСтовпчикОб'єднати кнопки паузи ті відтворенняКомандаКоментарКоментаряхКоментарі:Комерційна інформаціяКомпозиторСтиснуті модулі (*.bz2)Стиснуті модулі (*.gz)Стиснуті модулі (*.gz, *.bz2)Рівень стискання: НормальнийСтискання: Дуже сильнеСтискання: ШвидкеСтискання: СильнеСтискання: БожевільнеСтискання: НормальнеДиригентЗ'єднання через HTTP-проксіПід'єднання до сервера CDDB...Таймаут з'єднання [сек]:Контактна інформаціяТип вмістуПомилка перетворення у полі %s: '%s' не відповідає формату '%s'!Перетворення до цільового кодування не вдалосяПеретворити підкреслювання на пробілКопіюватиАвторське правоАвторське право/юридична інформаціяГоловний дизайн, розробка та програмування: Виправити існуючий записНеможливо завантажити зображення з: %sОбкладинкаСтворити новий каталогСтворити каталогСтворити пусте сховищеСтворити порожнє сховище...Створити підкаталоги для альбомівСтворити підкаталоги для виконавцівПоточний файл:Вирізати обранеDSPДатаДебютний альбомПідтримка декодування:Ширина обкладинки за замовчуванням:Видалити завантажені елементи з файлової системиОписОпис:ПризначенняВиявляти зміну носіяПристрій зайнятий. (Aqualung не зміг встановити свій інтерфейс.)Пристрій не відповідає. Спробуйте поворушити руків'ям.Шлях до пристрою:Пряме з'єеднання з ІнтернетомКталог '%s' буде видалено разом із усім вмістом. Бажаєте продовжити?Відповідно до каталогівНазвою каталогаНазвою каталога (нижній регістр)Структура каталогівВимкнути усі розширенняВимкнути рельєф кнопок керуванняЗаборонити ручне витягуванняВимкнути підтримку жупанівДискІнформація про дискІнформація про диск...Скасувати зміниНе закриватиНе виходитиНе збільшувати зображення меншої шириниНе перекодувати файли, що задовільняють маску:Не перекодувати файли, що вже у форматі призначенняНічого не робитиБажаєте зберегти сховище "%s" перед видаленням з Музичного Сховища?Бажаєте зберегти сховище перед видаленням?Не показувати мініатюру обкладинки у головному вікніЗробленоКаталог завантаження:Завантаження %d/%d (%d%%) ...Перетягуйте пункти у списку для встановлення порядку стрічок у Музичному Сховищі.Перетягуйте пункти у списку нижче для встановлення порядку стовпчиків у списку пргравання.Інформація приводуІнформація приводу...Нехтувати випадковими відхиленнями, базуючись наДва каналаТривалість:Під час виконанняПід час записуEAN/UPCРедагувати виконавцяРедагувати записРедагувати СховищеРедагувати доріжкуРедагувати виконавця...Редагувати стрічкуРедагувати властивості стрічкиРедагувати елемент...Редагувати запис...Редагувати сховище...Редагувати доріжку...ВитягтиАдреса електроної пошти для підписки:Вбудувати список програвання у головне вікноНаголос:Наголос: немаєНаголос: резервнийДозволити значки вузлів дерева Музичного СховищаЗадіяти усі розширенняЗадіяти Автоматичне Вирівнювання Гучності (RVA)Переміжний колір рядків у спискуУвімкнути рядок стануУвімкнути рядок стану у Музичному СховищіУвімкнути рядок стану у списку програванняУвімкнути системний лотокУвімкнути панель інструментівУвімкнути панель інструментів у Музичному СховищіУвімкнути підказкиДозволити значки вузлів дереваДозволенийЗакодованоЧас кодуванняПідтримка кодування:Поставити в чергу список програванняПомилкаПомилка перетворення поля %s на Рік: '%s' не є цілим числом!Помилка у рядку форматуПомилка у рядку формату заголовкаТільки повний збігВиключити файли, що задовільняють маскуРозгорнути сховища після запускуОчикувалося '}' після '{', але знайдено кінець рядку.Експорт усіх елементів...Експорт виконавця...Експорт файлівЕкспорт елементу...Експорт нових елементів...Експорт запису...Експорт сховища...Експорт доріжки...Експорт файлівФайли розширеного форматування заголовка (*.lua)Додаткові дані:Картинки FLACНеможливо встановити метадані для наступних файлів:Неможливо записати метадані до файлу. Причина: %sФайлФайл "%s" не існує, або вас позбавлено права на його запис. Перевірте, чи не відмонтовано розділ, що містить файл сховища.Файл '%s' буде видалено. Бажаєте продовжити?Власник файлуТип файлуФормат файлу:Іконка файлу (32x32 PNG)Значок файлу (інше)Інформація про файлІнформація про файлФайл не доступний на записНазва файлу:Файл:Назва файлуШаблон імені файлу:Назва файлу:Обрані для видалення файлиФайлова системаФільтрТільки перше словоСлідує структурою каталогів для визначення виконавців та записів. Файли додаються на основі записів.ШрифтиПримусово перечитувати таблицю файлів при кожному скануванні дискуПримусово:Перетворити інши літери до нижнього рогіструФорматФормат:Free Lossless Audio Codec (*.flac)Free Lossless Audio Codec (FLAC) Вільне місцеФранцузька: Передня обкладинкаГоловнеЗагалні метадані потокуЖанрЖанр:Німецька: Графіка:HTTP (порт 80)Жорстко скинути пристрійДопомогаСховати AqualungПриховати панель коментарівПриховати панель коментарів Музичного СкладуДомашня сторінка:Горизонтальне колесо миші:Угорська: IDID3v1ID3v2ISBNISRCОпис станції (Icy-Description)Жанр станції (Icy-Genre)Назва станції (Icy-Name)БездіянняІлюстраціяНеявний командний рядокІмпортувати тег коментаряІмпортувати тег Replaygain як ручне налаштування RVAІмпортувати як ВиконавцяІмпортувати як рівень RVAІмпортувати як ЗаписІмпортувати як ключ для сортуванняІмпортувати як НазвуІмпортувати як № доріжкиІмпортувати як РікУ будь-якому разіВключити тільки файли, що задовільняють маскуНезалежнийЗмістПочатковй ключВходиІнструментиІнструменти:Внутрішня помилкаІнтернетНазва інтернет-радіостанціїВласник інтернет-раідостанціїІнтерпретація/РеміксВступНевірне значення поля 'Жанр'Невірне значення поля 'Номер трека'Інвертувати поточний станПеревернути вибірУчасникиСхоже, рік вказано невірно. Бажаєте продовжити?Італійська: Аудіо сервер JACK Налаштування порту JACKЗ'єднання з JACK втраченоJACK було вимкнено, або він від'єднав Aqualung, бо той був недостатньо швидкий. Все, що ви можете тепер зробити, це перезапустити обидва JACK та Aqualung.Налаштування порту JACKЯпонська: Об'єднане стереоРозміщувати головне вікно завжди зверхуКлюч: Будівельник патчів LADSPAОбробка додатку LADSPAПідтримка розширень LADSPA LAME (MP3) LAVC (AC3, AAC, WavPack, WMA, etc.) LAVC аудіо/відео файлиКол лейблаМоваШар IШар IIШар IIIВедучий співак/виконавецьВкладишЛіву та праву клавіші миші зарезервовано.Ліва клавішаТривалістьДовжина:ЛіцензіяМежіЛінійному порозі [дБ]Лінійний поріг [дБ] :Оточення прослуховування:ВітальняЗавантажити список програванняЗавантажити список програвання у нову вкладкуЗавантажити налаштування з файлу Музичного СховищаЛокальний каталог CDDB:РозташуванняМесце розташування та ім'я файлуЛоготип, іконки: Підтримка зацикленого відтворення Діапазон повтору: %d-%d%%Діапазон повтору: %d-%d%% [%s - %s]Підтримка Lua (програмоване форматування заголовка) Поет/автор текстуПоет/автор текстуТип MIME: %sMOD Audio (MOD, S3M, XM, IT, etc.) МОНОСписок програвання MP3 (*.m3u)MPEG Audio (*.mp3, *.mpa, *.mpega, ...)MPEG Audio (MPEG 1-2.5 Layer I-III) Метадані MPEG-потокуГоловне вікноЗбіги:Максимальна кількість елементів:Максимальна кількість спроб:Максимальний використаний простір [Мб]:НосійПомилка виділення пам'ятіМетаданіРедактор метаданих (діалог інформації про файл)Середня клавішаРізнеРежим:Модель:Інформація про модульМодулі (*.xm, *.mod, *.it, *.s3m, ...)Monkey's Audio Codec Monkey's Audio Codec (*.ape)НастрійПакетний запис (Mount Rainier)Клавіша мишіКлавіші мишіКолесо мишіКадр з кіно/відеофільмуМультимедіа плей-ліст (*.pls)Musepack Musepack (*.mpc)Вирівнювання гучності MusepackМузичне СховищеФайли Музичного Сховища (*.xml)Музичне Сховище: Подяки музикантівПриглушитиNULLІм'яІм'я для сортування:Перетворення іменіІм'я:Нова вкладкаНаступна пісняНаступна пісняНемає дискаСхожих записів не знайдено.Немає підтримки метаданих для цього форматуНемає виводуНе використовувати проксі для:Придатного пристрою iRiver iFP не знайдено. Можливо, він від'єднаний або вимкнений.№Галаслива майстерняНемаєЖодна з обраних пісень не має формату, що підтримується вашим плеєром. Бажаєте продовжити?Зауваження: існуючі теги будуть оновлені навіть якщо вони не обрані тут.OSS Audio ОфісОфіційна веб-сторінка виконавцяОфіційна веб-сторінка аудіофайлуОфіційна веб-сторінка джерела аудіоОфіційна веб-сторінка радіостанціїOgg Speex Ogg Speex (*.spx)Ogg Vorbis Ogg Vorbis (*.ogg)Коментарі Ogg XiphОдне або більше совище в Музичному Сховищі було змінено. Бажаєте зберегти їя перед виходом?Одна з пісень має формат, що не підтримується вашим плеєром. Бажаєте продовжити?Тільки якщо не виміряноСумісність з OpenBSD, трюки з метаданими: Додаткові можливості:ОрганізаціяОригінальна назва альбомуОригінальне ім'я виконавцяОригінальна назва файлуОригінальне ім'я поетаЧас випуску оригіналаІншеВихідПідтримка драйверів виводу:Вихід:ВиходиРазом:Перекривати установки жупанаParanoiaКорекція помилок ParanoiaЧастина наборуШляхШляхи мають бути абсолютними або починатися із тильди, яку буде перетворено на домашній каталог користувача. Перетягніть записи у списку, щоб встановити порядок зберігання у Музичному Сховищі.Шляхи мають бути абсолютними або починатися із тильди.Шляхи до баз даних Музичного СховищаПатернів:ПаузаСплатаВиконувати читання із перекриваннямВиконавецьПорядок сортування виконавцівТип зображення:ГратиГрати CD AudioГрати/ПаузаПрогравати/Зупинити піснюГрати/Зупинити піснюАВГ (RVA)АВГ (RVA) зараз вимкнено. Бажаєте увімкнути його зараз?Список програванняЗатримка списку програванняПорядок стовпчиків списку прграванняСписок програвання: Уведіть, будь ласка, нове ім'я.Уведіть, будь ласка, назву каталога.Будьласка оберіть базу даних Музичного Сховища.Будь ласка, оберіть файл програмованого форматування заголовка.Будь ласка, оберіть локальний шлях.Будь ласка, оберіть хоча б одну дійсну пісню зі списку програвання.Будь ласка, оберіть аудіофайл для цієї доріжки.Будь ласка, оберіть аудіофайли для цього запису.Будь ласка, оберіть каталог для експортованих файлів.Будь ласка оберіть каталог для добутих файлів.Будь ласка, оберіть каталог завантаження для цього подкаста.Будь ласка, оберіть кореневий каталог.Будьласка оберіть xml файл для цього складу.Будь ласка, вкажіть файл, з якого буде завантажено зображення.Будь ласка, вкажіть файл, з якого буде завантажено список програвання.Будь аска, вкажіть файл для збереження зображення.Будь ласка, вкажіть файл для збереження списку програвання.URL подкаста:Підтримка подкастів ПодкастиПорт:Позиція: %d%%Постпідсилювач (після Гучності та Баланса)Передпідсилювач (до Гучності та Баланса)Передвстановлені перетворенняПопередня пісняПопередня пісняОбробка метаданихПрогрес:ПродюсерПрофіль: Без башніПрофіль: БожевільнийПрофіль: РадіоПрофіль: СтандартПрофіль: ТелефонПрофіль: ЕскізПрофіль: ЕкстремальнийФайл програмованого форматування заголовкаПрограмування, розробка ГІК: ПрогресПрогрес:Протокол для запитів (лише пряме з'єднання):Адреса проксі:Налаштування проксіПрава на публікаціюВидавникОфіційна веб-сторінка видавцяЛоготип видавця/студіїPulseAudio Кнопки керування знизу списку програванняВихідАВГ (RVA)Рівень RVA для незміряних файлів [дБ] :Значення RVAЧитати CD+GЧитати CD-DAЧитати CD-RЧитати CD-RWЧитати DVD+RЧитати DVD+RWЧитати DVD-RЧитати DVD-RAMЧитати DVD-ROMЧитати DVD-RWЗчитувати ISRC (Міжнародний стандартний номер запису)Зчитувати MCNЧитання Mode 2 Form 1Читання Mode 2 Form 2Зчитувати кілька сесійЧитанняЧитання файлуСправді видалити "%s" з Музичного Сховища?Справді видалити "%s" з Музичного Сховища?Справді видалити сховище "%s" з Музичного Сховища?ПричинаЗаписДата записуМісце записуНазвою записуНазвою запису (нижній регістр)Назвах записівМісце запису/студіяРекурсивний пошук аудіофайлів, починаючи із кореневого каталога. Файли обробляються незалежно, так що доступні тільки метадані та перетворення імен файлів.Опорний рівень [дБ повна шкала] :ОновитиРегулярний вираз співпадає із порожньою строкоюРегВир:Регулярний виразПов'язана інформаціяДата випускуВидалитиВадалити виконавцяВидалити записВидалити СховищеВидалити доріжкуВидалити всіВидалити виконавцяВидалити мертвіВидалити стрічкуПрибрати розширення файлуВидалити файлиВидалити елемент...Прибрати число на початкуВидалити неіснуючі файли зі сховищаВидалити застарілі елементи [день]:Видалити записВидалити обраніВидалити обрані пісні зі списку програвання (Натисніть праву кнопку миші для відкриття меню)Видалити сховищеВидалити доріжкуВидалення неіснуючих файлівПерейменуватиПерейменувати список програванняПеревпорядкувати стрічкиПовторювати всі пісніПовторювати поточну піснюЗаміна:Коефіцієнт підсилення альбома для вирівнювання гучності (ReplayGain)Пік альбома для вирівнювання гучності (ReplayGain)Опорна гучність Вирівнювання Гучності (ReplayGain)Коефіцієнт підсилення доріжки для вирівнювання гучності (ReplayGain)Пік доріжки для вирівнювання гучності (ReplayGain)Тег ReplayGain для використання (із відходом на інший):Replaygain_track_gainReplaygain_track_gainПеречитати дані для існуючих доріжокПеречитати матадані файлуПрескануватиПоновитиОтримання збігів з сервера...Перегляд:Права клавішаДістати музикуДістати музику з CDДістати музику з CD...Діставання доріжок з CDСкотитися до активної пісніКореневий шлях:Запущені розширенняРосійська: Тип SRC: СТЕРЕОЗУПИНКАПідтримка конвертера частоти дискретизації Тип перетворювача частоти дискретизаціїЧастота дискретизації:ФрагментиФрагментів:ПісочницяЗберегтиЗберегти усі списки програванняЗберегти всі сховищаЗберегти та закритиЗапис та відновлення списку програвання при виході/запускуЗберегти список програванняПеріодично зберігати список програвання [хвил.]:Зберегти сховищеСканування файлівШукатиШукати у:Пошук Музичному СховищіШукати у списку програванняШукати...ВибратиОбрати шрифт...Вибрати всеОбрати усі пісні у списку програвання (Натисніть праву кнопку миші для відкриття меню)Оберіть тим збіркаОбрати каталогОбрати файлиОбрати перший та закрити вікноОбрати диск у CD-чейнджеріЗняти вибірОбрані файли:Надіслати до пристрою iFPОкремоВстановити підзаголовокВстановити швидкість приводуНалаштуванняПоказати AqualungПоказати значення RVAВиділяти жирним активну доріжкуПоказувати кнопку закриття на вкладціПоказувати мініатюру обкладинки тільки для треків з Музичного СховищаПоказувати приховані файли та каталоги у діалогах вибору файуПоказувати назву пісні у заголовку головного вікнаПоказувати розмір файлу у статусному рядкуПоказувати вкладку тегів першою у вікні інформації про файлПоказати тривалість доріжокПеремішати пісніСпрощений вигляд будівельника патчів LADSPAОдин каналРозмірВибір жупанівПідтримка жупанів, вигляд та поведінка, програмування ГІК: Маленькі таймери:ПрограмаПісня у списку програвання: Інформація про пісню:Назва пісні: Сортувати виконавців заСортувати записи заЗвукові файли (*.wav, *.aiff, *.au, ...)ДжерелоВихідний файл:Запускати мінімізованимСтатусний рядок:Крутість [дБ/дБ] :СтереоСтопЗупинити додавання файлівЗупинити додавання пісеньСтруктура:Максимальна довжина імені підкаталога:Надіслати дані про цей CD до бази даних CDDB...Надіслати новий записНадіслати запис до бази даних CDDB...Підписатися на нову стрічкуПідзаголовокУспішноШведська: Системний лотокПідтримка системного лотка Увести метадані у файлиЧас внесення тегаТеги, які додавати при створенні чи зміні аудіофайлів MPEG:Каталог призначення для добутих файлів.Каталог призначення:Файл призначення:ТестАдреса електронної пошти, вказана для підписки, недійсна.Інформація нижче отримана з приладу і може не відображати дійсних можливостей приладу.Обрані файли буде видалено з файлової системи. Відновлення буде неможливим після цієї операції. Бажаєте продовжити?Обрана пісня має формат, що не підтримується вашим плеєром. Бажаєте продовжити?Вказане сховище вже додано до списку.Сховище '%s' вже існує. Додайте його на вкладці Налаштування/Музичне Сховище.Є незбережені зміни у метаданих файлу.Цей файл Aqualung скомпільовано з:Цей диск не містить інформації CD-TextЦю клавішу вже призначено.Ця програма є вільним програмним забезпеченням; ви можете поширювати його та/або змінювати на умовах Універсальної громадської ліцензії GNU у тому вигляді, у якому її було опубліковано Фондом вільного програмного забезпечення; як версії 2, так і (за вашим розсудом) будь-якої більш пізньої версії. Ця програма поширюється у надії, що вона буде корисною, але БЕЗ ЖОДНОЇ ГАРАНТІЇ; навіть без обов'язкової гарантії ТОВАРНОЇ ПРИДАТНОСТІ або ПРИДАТНОСТІ ДО ПЕВНОГО ПРИЗНАЧЕННЯ. Для більш детальної інформації див. Універсальну громадську ліцензію GNU. Ви мали отримати копію Універсальної громадської ліцензії GNU разом з цією програмою; якщо ні, то напишіть у Фонд вільного програмного забезпечення: Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.Час очікування вводу/виводу сокета:НазваФормат назвиПорядок сортування назвНазва цілком у нижньому регістрі. Бажаєте продовжити?Назва цілком у верхньому регістрі. Бажаєте продовжити?Назва:Вимикач будівельника патчів LADSPAВимикач Музичного СховищаВимикач списку програванняРазомВсього семплів:Разом: ДоріжкаНомер доріжкиКоментар доріжкиДовжина доріжокНазва доріжкиНомер доріжкиНазви доріжокДоріжка:ДоріжкиПерекладачі:Обрізати пробіли на початку, в кінці та ті, що повторюютьсяТип: URL:Українська: Неможливо відкрити файлНеможливо видалити %d файл.Неможливо видалити %d файлівСкасувати закриття вкладкиНеочикуваний кінець рядку після '?'.Об'єднана мінімізація віконНевідомийНевідомий АльбомНевідомий виконавецьНевідомий записНевідома ДоріжкаПісля '%%%%' виявлено символ невідомого типу.Після '?' виявлено символ невідомого типу.Невідомий дискНевідома помилкаНеобмежена кількість спроб за помилок читання (ніколи не пропускати)НевиміряноТільки невиміряних доріжокНерозпізнаноБез назвиОновити усі стрічкиОновити стрічкуОновити метадані файлуОновити метадані файлів...Оновлення...Використовувати тільки базове ім'я замість повного шляху,якщо не доступні метадані.Використовувати свій рівень RVA [дБ]Використовувати відносні шляхи у файлі сховищаВикористовувати лише локальну базу данихТекст користувачаURL користувачаКодування зі змінним потокомПостачальникПостачальник:Перевірити цілісність данихВерсіяВертикальне колесо миші:Видиме ім'я:Рівень гучності:Гучність: %sПопередити мне, якщо менеджер вікон не підтримує системний лотокПопередженняWavPack WavPack (*.wv)При додаванні нових полів намагатися встановити їх вміст з еквівалентних полів іншого тега.У режимі перемішування записи, додані в режимі альбому, програються по черзіWin32 Sound API Записати CD-RЗаписати CD-RWЗаписати DVD+RЗаписати DVD+RWЗаписати DVD-RЗаписати DVD-RAMЗаписати DVD-RWЗаписРокомРік:Ви маєте вказати адресу електроної пошти для надсилання до CDDB.Вам знадобиться перезапустити Aqualung, щоб набули чинності наступні зміни:_Перервати_Додати файли..._Оглянути..._Налаштувати_Завантажити_Відвантажитивиконавецьвиконавцінайкращийбіт подвійнийбіт з рухомою комоюбіт знаковийбіт беззнаковийпідрахунок...деньднідискдискикодуванняшвидкострічкастрічкиполе:Менеджер пристрою iFP (режим завантаження)Менеджер пристрою iFP (режим відвантаження)Підтримка драйвера iRiver iFP елементелементиновий елементнові елементитільки читаннязаписзаписикорінь / виконавець / виконавець / виконавець / запис / доріжкакорінь / виконавець / виконавець / запис / доріжкакорінь / виконавець / запис / доріжкакорінь / запис / доріжкачитання/записсекундЗвукові файли (WAV) Звукові файли (WAV, AIFF, etc.) sndio Audio тег:доріжкадоріжкинедосяжнийвикористовувати ширину вікна оглядача